看板 Mathematica 關於我們 聯絡資訊
借 AmibaGelos 的文討論一下 MMA 中 AppendTo 的效率替代方案, 因為 AppendTo 的指令每次重新複製一次再加入新元素,又慢又吃記憶體, 但是 AppendTo/PrependTo名字取的好,所以造成許多無效率程式碼, 像是 Jon McLoone 的 10 Tips for Writing Fast Mathematica Code 中 7. Use Sow and Reap to accumulate large amounts of data (not AppendTo). 建議用 Sow and Reap 替代 AppendTo, 另外用 linked lists,例如以 set = {set, new} 取代 AppendTo[set,new] 最後再 Flatten,會有效率得多。 (A大的例子要多設個新head含seed相資訊, set = {set, infohead[newinfos]}), 找到一個相關網頁,連效率比較圖都畫出來給大家看: http:// stackoverflow.com/questions/8450779/prepend-vs-append-perf-in-mathematica 看了一下內文比較 AppendTo, linked lists 和 Join 指令的效率, 用 Join 最快,不過我覺得合理情況下應該用 set = Join[set, new] 指令來比較, 而不是 Join[startlist, datalist=Table[newdata,...]]來比較效率。 ※ 引述《AmibaGelos (Amiba Gelos)》之銘言: : 最近在用MMA跑Monte Carlo,覺得MMA不能提取seed實在是很不方便,所以就做了一個可以 : 提取seed的RandomVariate : Module[{seed, store = {}, temp = 1, Storing}, : RandomMemory[1, opt___] := RandomMemory[temp, opt]; : RandomMemory[in__] := (Storing[in]; RandomVariate[in]); : Storing[dist_, opt___] := : AppendTo[ : store, {Evaluate[If[dist === temp, 1, temp = dist]], opt}]; : SetSeed[InSeed_, InStore_: {}] := (store = {}; temp = 1; : SeedRandom[seed = InSeed]; (RandomMemory[##];) & @@@ InStore;); : ExtractSeed[] := {seed, store}; SetSeed[0];]; : 這個設計在跑custom distribution的時候蠻好用的, 不過AppendTo會是瓶頸 : 目前只有想到hash, 不過有新distribution還是得重建table : 不知道有沒有更漂亮的寫法? -- At the end, it never ends. -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.115.45.65 ※ 文章網址: https://www.ptt.cc/bbs/Mathematica/M.1476269699.A.534.html
AmibaGelos: Linkedlist要做container速度不會比Join快吧 10/12 21:50
AmibaGelos: join速度很快蠻怪的...這樣Append/Prepend是做心酸嗎 10/12 22:03
ginstein: 最快應該是Sow/Reap,最適合A大題目的應該是linkedlists 10/12 22:11
ginstein: Join最快是因為測試碼直接生成所需資料再Join,當然最快 10/12 22:12
ginstein: Join連資料的速度比Flatten指令解linkedlist結構快的 10/12 22:14
ginstein: 若loop中用set=Join[set,new]的話,Join不會比較快 10/12 22:15
AmibaGelos: 喔喔這樣看來確實是該用linkedlist! 10/12 22:18