時間復雜度是一個函數,它定量描述了該算法的運行時間。
常見的時間復雜度有以下幾種。
1,log(2)n,n,n log(2)n ,n的平方,n的三次方,2的n次方,n!
1指的是常數。即,無論算法的輸入n是多大,都不會影響到算法的運行時間。這種是最優的算法。而n!(階乘)是非常差的算法。當n變大時,算法所需的時間是不可接受的。
用通俗的話來描述,我們假設n=1所需的時間為1秒。那么當n = 10,000時。
- O(1)的算法需要1秒執行完畢。
- O(n)的算法需要10,000秒 ≈ 2.7小時 執行完畢。
- O(n2)的算法需要100,000,000秒 ≈ 3.17年 執行完畢。
- O(n!)的算法需要XXXXXXXX(系統的計算器已經算不出來了)。
可見算法的時間復雜度影響有多大。
假如一張表有一億條數據 ,需要查找其中某一條數據,按照常規邏輯,一條一條的去匹配的話,最壞的情況下需要匹配一億次才能得到結果,用大O標記法就是O(n)最壞時間復雜度。
這是無法接受的,而且這一億條數據顯然不能一次性讀入內存供程序使用, 因此,這一億次匹配在不經緩存優化的情況下就是一億次IO開銷,以現在磁盤的IO能力和CPU的運算能力,有可能需要幾個月才能得出結果 。
如果把這張表轉換成平衡樹結構(一棵非常茂盛和節點非常多的樹),
(圖示:該樹只有三個節點)
假設這棵樹有10層,那么只需要10次IO開銷就能查找到所需要的數據, 速度以指數級別提升,用大O標記法就是O(log n),n是記錄總樹,底數是樹的分叉數,結果就是樹的層次數。換言之,查找次數是以樹的分叉數為底,記錄總數的對數,用公式來表示就是
\[\log_{樹的分叉數}{記錄總數} = 查找次數 \]
用程序來表示就是Math.Log(100000000,10),100000000是記錄數,10是樹的分叉數(真實環境下分叉數遠不止10), 結果就是查找次數,這里的結果從億降到了個位數。因此,利用索引會使數據庫查詢有驚人的性能提升。