[闲聊] AppendTo 指令的效率替代方案

楼主: ginstein (迈向学术之路)   2016-10-12 18:54:54
借 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
: 不知道有没有更漂亮的写法?
作者: AmibaGelos (Amiba Gelos)   2016-10-12 21:50:00
Linkedlist要做container速度不会比Join快吧join速度很快蛮怪的...这样Append/Prepend是做心酸吗
楼主: ginstein (迈向学术之路)   2016-10-12 22:11:00
最快应该是Sow/Reap,最适合A大题目的应该是linkedlistsJoin最快是因为测试码直接生成所需资料再Join,当然最快Join连资料的速度比Flatten指令解linkedlist结构快的若loop中用set=Join[set,new]的话,Join不会比较快
作者: AmibaGelos (Amiba Gelos)   2016-10-12 22:18:00
喔喔这样看来确实是该用linkedlist!

Links booklink

Contact Us: admin [ a t ] ucptt.com