大致分爲:事前估算(設計算法以前就估算此算法性能)和過後估算(運行後,經過收集數據)算法
直覺上覺得是過後估算爲主,畢竟,實踐是檢驗真理的標準嘛。過後收集數據纔是比較靠譜的。數據庫
不過,想法錯了。如今才明白,以"事前估算"爲主要辦法。函數
爲何過後估算的辦法不怎麼使用呢?性能
一、輸入的數據量無法真實模擬。好比輸入的數據量是100,兩種算法之間並不明顯差別。而輸入的數據量是100萬的時候,纔會看到明顯的差別。但在咱們的實驗環境下,很難作到這麼真實的測驗,缺少這種環境。若是都放到過後去估算,由於無法真實測驗,那就會很麻煩。測試
個人一個實際感覺是,在數據庫測驗中,即使咱們在實驗環境下,能夠模擬輸入100萬行數據,我只有5個字段的行。但在真實的應用環境下,100萬數據又比這複雜些。會有10個字段的行。spa
二、受制於硬件環境。兩種算法,a算法比b算法好。但b算法是在性能優越的機器上測驗,因此沒看出比a算法差在哪裏,結果是兩個算法看不出明顯的差異。設計
最終,硬件好能夠掩蓋比較劣質的算法,劣的算法看不出有多劣質。內存
那是否是說,讓兩種算法在一樣的機器上來測驗就ok了呢?我也嘗試尋找對這個疑惑的解釋,留在這裏。有質疑纔會有進步io
找到了解釋,即使在一樣的機器上來進行測試,但因爲計算機的內存使用率、cpu使用率是動態變化的,使用狀況不一樣,形成的測試結果也會不一樣。for循環
事前估算主要跟數據輸入量、運行次數兩個因素有關。
瞭解幾個術語與符號表示,由於業界都是這些術語與符號來描述,若是不清楚,就難以看懂他們的要表達的意思
T(n)
f(n)
有些解釋太文縐縐了,繞來繞去,我沒怎麼理解。
算法的時間複雜度記作:T(n)=O(f(n));
個人理解:
T是英文單詞的time的簡寫,T(n)表示算法要執行的時間耗費。
F應該是,Frequency Count的簡稱。理解爲次數的意思。
每條語句的執行時間=語句的執行次數(即頻度(Frequency Count))×語句執行一次所需時間。
每條語句就是程序中的一句代碼。好比一句代碼習慣用分號";"來結束。這個我以爲沒必要糾結很細。能夠是一個函數的調用,若是在for循環中,只算多少次循環就能夠了。
計算一個算法的複雜度分爲兩個方面:時間複雜度和空間複雜度。
時間複雜度,就是執行這個算法須要耗費多長時間,這是通俗解釋了。
空間複雜度,就是執行這個算法須要多少內存空間(由於最終計算都是在內存中進行,不是在磁盤中)
先不須要了解如何計算一個算法耗費多少內存,看看須要執行多長時間,怎麼計算
下面解釋了原因:
一個算法執行所耗費的時間,從理論上是不能算出來的,必須上機運行測試才能知道。但咱們不可能也沒有必要對每一個算法都上機測試,只需知道哪一個算法花費的時間多,哪一個算法花費的時間少就能夠了。而且一個算法花費的時間與算法中語句的執行次數成正比例,哪一個算法中語句執行次數多,它花費時間就多。一個算法中的語句執行次數稱爲語句頻度或時間頻度。
我喜歡上面這麼通俗的解釋,意思是,測驗一個算法是時間複雜度,可靠的辦法是對運行期間執行的操做次數進行統計,由於操做次數越多,耗費的時間確定越多。
算法的準確執行時間算不出來(由於在不一樣硬件、內存佔有狀況下執行時間不一樣),只能經過運行次數來間接判斷(這樣拋開了硬件環境等影響)。執行次數越多的算法確定越很差。
因而:時間複雜度計算,變成了對執行次數進行統計。那怎麼統計執行次數,用什麼來表示呢?
用f(n)來表示:輸入量爲n的狀況下,執行次數是多少。f(n)是一個函數。
關於函數的漸近增加的理解:f(n)的漸近增加大於g(n),就是表示隨着n輸入值變大,f算法的執行次數要大於g算法,因此漸近增加值越大,算法越很差。
最終:根據"測驗時間複雜度最終是測驗執行次數"這個方式,咱們只要測量f(n)的狀況,就能側面測驗時間複雜度T(n)了。
T(n)=0(f(n)) 時間複雜度經常使用大O符號表述
表示,算法執行時間的增加率和f(n)的增加率相同。這裏面相同業界命了一個名稱,漸近時間複雜度,簡稱爲時間複雜度。
能夠看出,這個時間複雜度,是一個近似的值,就像命名那樣子,漸近(的)時間複雜度。
總結:事前估算法,可以作到拋開硬件、軟件因素影響算法的測驗。