Mathematica,提高循环中appendto的速度

时间:2016-09-20 16:22:01

标签: performance loops optimization append wolfram-mathematica

如何改进以下功能?目前它很慢。提前谢谢。

    discounts[firstDFF_] :=
        Module[ 
            {len = Length[swapdata], running = firstDF, newdisc, disclist = {firstDFF}, k = 2},

            Do[
                newdisc = (1 - swapdata[[k]]*running)/(1 + swapdata[[k]]);

                running += newdisc;

                AppendTo[disclist, newdisc]
                , 
                {k, 1, len}
            ];

            disclist
        ];

用于在引导过程中获取折扣因子列表。

2 个答案:

答案 0 :(得分:1)

只需使用disclist = {disclist, newdisc} Flatten代替AppendTo[disclist, newdisc],代码就会从14.59秒加速到0.34秒。

以下演示。首先是OP的原始代码。

swapdata = ConstantArray[0.03, 100000];

firstDF = 1;

discounts[firstDFF_] := Module[{len = Length[swapdata],
    running = firstDF,
    newdisc,
    disclist = {firstDFF}, k = 2},
   Do[newdisc = (1 - swapdata[[k]]*running)/(1 + swapdata[[k]]);
    running += newdisc;
    AppendTo[disclist, newdisc], {k, 1, len}];
   disclist];

First[{time, result1} = Timing[discounts[100]]]
  

14.594

discounts[firstDFF_] := Module[{
    len = Length[swapdata],
    running = firstDF,
    newdisc,
    disclist = {firstDFF}, k = 2},
   Do[newdisc = (1 - swapdata[[k]]*running)/(1 + swapdata[[k]]);
    running += newdisc;
    disclist = {disclist, newdisc}, {k, 1, len}];
   Flatten@disclist];

First[{time, result2} = Timing[discounts[100]]]
  

0.343

result1 == result2
  

答案 1 :(得分:1)

还有几种方法。这些只比ChrisD的Do .. disclist = {disclist, newdisc} ..

略快
discounts[firstDFF_] := 
  Module[{len = Length[swapdata], running = firstDF, newdisc},
   Join[{firstDFF}, Table[
     newdisc = (1 - swapdata[[k]]*(running))/(1 + swapdata[[k]]);
     running += newdisc;
     newdisc, {k, 1, len}]]];
First[{time, result} = Timing[discounts[100]]]

discounts[firstDFF_] := Module[{running = firstDF, newdisc},
   Join[{firstDFF}, (
       newdisc = (1 - #*running)/(1 + #);
       running += newdisc;
       newdisc) & /@ swapdata]];
First[{time, result} = Timing[discounts[100]]]

discounts[firstDFF_] :=
  Reap[Sow[firstDFF];
    Fold[#1 + Sow[(1 - Times@##)/(1 + #2)] &, firstDF  ,
       swapdata]][[2, 1]];
First[{time, result} = Timing[discounts[100]]]