推 chchwy:你這招叫loop unrolling,現在大部分的編譯器都會幫做了 12/21 20:20
我只是覺得這個比較適當拿來當例子
也沒想到更好的
如果不認同我第一點或者有更好的例子的話
可以提出來:P
※ 編輯: thinkniht 來自: 1.161.22.157 (12/21 20:27)
※ 編輯: thinkniht 來自: 1.161.22.157 (12/21 20:27)
→ atst2:有時候效能的差, 跟輸入的數量級是有關的, 不同的演算法 12/21 20:46
→ atst2:在輸入少量的時候可能沒什麼差異,但到一定數量級以上,差別 12/21 20:46
→ atst2:就出來了. 12/21 20:46
→ atst2:舉個例子來說, iOS現在有提供Fast Enumerate,另外也有提供 12/21 20:47
→ atst2:Concurrent Enumerate, 一般情形下,Fast Enumerate應該是最 12/21 20:48
→ atst2:快的,但在多核心的情況下,理論上Concurrent Enumerate,要 12/21 20:49
→ atst2:比Fast Enumerate更快. 可是實質上,要讓Concurrent Enu有用 12/21 20:49
→ atst2:資料最少要一百萬筆以上.那這樣的技術,在mobile device上, 12/21 20:50
→ atst2:用處就很少了,不如直接使用Fast Enumerate。 12/21 20:50
→ atst2:有時候,為了追求在實際的情景下無法發揮的效能,花太多心思 12/21 20:51
→ atst2:並不見得是好事. 12/21 20:52
→ atst2:但做為興趣來實證一下,倒也是不錯. 12/21 20:52
推 snaketsai:迴圈整開的話,編譯器有下優化選項應該都會作 12/22 01:26
→ snaketsai:像Gcc如果懶得調組合,下-O3就會作迴圈展開跟行內函式 12/22 01:27
→ snaketsai:抱歉講錯,要獨立開 -funroll-loops 這個選項的樣子@@ 12/22 01:29
→ snaketsai:不過有些有些優化真的要手動去作,像是函數餵指標: 12/22 01:35
推 ckaha:不太懂調這些跟現代在處理的演算法的設計理念孰重孰輕 12/22 12:51
→ ckaha:一個要針對平台語言case by case 一個演算法在針對現有問題 12/22 12:52
→ ckaha:當陷入針對一個迴圈最佳化而且可能只有C/C++才能使用的技巧 12/22 12:53
→ ckaha:是不是應該要切出來給專業人士去弄 12/22 12:53
推 genius945:個人感覺是演算法是比較宏觀的,但這邊討論的有點像是同 12/22 13:57
→ genius945:樣O(n)的線性時間,在實務上如何讓5n化為n這樣@@" 12/22 13:57
我遇過一個情況 細節不方便說太細
這邊大概描述一下:
原本寫法是這樣的
有個兩層迴圈
[第一個迴圈 變數為i]
{
[第二個迴圈 變數為j]
{
...
//使用i和j分別取得對應的資料和做處理
}
}
我後來改成:
[第一個迴圈 變數為i]
{
使用i取得對應的資料,並存入區域變數中
[第二個迴圈 變數為j]
{
...
//使用j分別取得對應的資料和使用區域變數做處理
}
}
一般算時間複雜度的話...
我想兩種寫法都是O(n^2)
但是第二種寫法是把在第二層迴圈中會做的事情抽出迴圈外
很理所當然的...因為執行次數減少,所以執行時間也被減少了...
這種情況在當時處理的程式出現過很多次
累積的[使用i取得對應的資料]的次數並不少
這類的做法後來減少了不少執行時間而且也不影響輸出結果
另外這[取得對應的資料]都會產生新的實體
減少執行次數不僅減少執行時間,同時也能減少建立的實體的次數
雖然不過就區域變數而已,之後會自動被GC...
但是這樣的區域變數數量一多...對時間與空間的影響也是不該忽視的
這也就是我想表示的...
有時實作演算方法的寫法也很重要
※ 編輯: thinkniht 來自: 114.42.237.20 (12/23 22:25)
→ PEIRON:這樣類似把2n^2 改成 n + n^2 ,big O 上看不出差異 12/24 20:23
→ PEIRON:但實際上的確有差 12/24 20:23
→ PEIRON:基本上跟 genius 舉的 5n 跟 n 意思差不多呢 12/24 20:26