【代碼優化方法論01】衡量程序運行效率——複雜度


1. 衡量標準

計算機通過一行行代碼去完成某個任務,實際上就是對輸入數據進行加工處理,並得到結果的過程。可見,編寫代碼的核心就是要完成計算。對於同一個計算任務,不同計算方法得到結果的過程複雜程度是不一樣的,對應的代碼運行效率也不一樣。

因此,複雜度是是衡量代碼運行效率的標準。

我們再想一想,一段代碼消耗的資源是什麼呢?
通常,代碼在執行過程中會消耗計算時間和計算空間(內存),那需要衡量的就是時間複雜度和空間複雜度。

2. 如何計算複雜度?

複雜度是一個關於輸入數據量 n 的函數。假設你的代碼複雜度是 f(n),那麼就用個大寫字母 O 和括號,把 f(n) 括起來就可以了,即 O(f(n))。
比如,O(n) 表示的是,複雜度與計算實例的個數 n 線性相關;O(logn) 表示的是,複雜度與計算實例的個數 n 對數相關。
通常,複雜度的計算方法遵循以下幾個原則:

  1. 複雜度與具體的常係數無關。例如 O(n) 和 O(2n) 表示的是同樣的複雜度。
  2. 多項式級的複雜度相加的時候,選擇高者作爲結果。例如, O(n²+n)=O(n²)+O(n) =O(n²)。
  3. O(1)表示常數複雜度。即複雜度與輸入量n無關,是一個定值。

3. 時間複雜度與代碼結構的關係

從本質來看,時間複雜度與代碼的結構有着非常緊密的關係;空間複雜度與數據結構的設計有關。
下面,總結了一些代碼結構與時間複雜度的關係:

  • 一個順序結構的代碼,時間複雜度是 O(1)。
  • 二分查找,或者更通用地說是採用分而治之的二分策略,時間複雜度都是 O(logn)。
  • 一個簡單的 for 循環,時間複雜度是 O(n)。
  • 兩個順序執行的 for 循環,時間複雜度是 O(n)+O(n)=O(2n),其實也是 O(n)。
  • 兩個嵌套的 for 循環,時間複雜度是 O(n²)。

4. 優化代碼的必要性

通常在小數據集上,時間複雜度的降低在絕對處理時間上沒有太多體現。但在當今的大數據環境下,時間複雜度的優化將會帶來巨大的系統收益。
假設某個計算任務需要處理 10萬 條數據。你編寫的代碼:

  • 如果是 O(n²) 的時間複雜度,那麼計算的次數就大概是 100 億次左右。
  • 如果是 O(n),那麼計算的次數就是 10萬 次左右。
  • 如果是O(log n) 的複雜度,那麼計算的次數就是 17 次左右(log 100000 = 16.61,計算機通常是二分法,這裏的對數可以以 2 爲底去估計)

可見,降低時間複雜度,能大大降低計算機計算次數,從而節省了很多處理時間。

參考鏈接:https://kaiwu.lagou.com/course/courseInfo.htm?courseId=185#/detail/pc?id=3339

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章