2011-11-11 99 views
12

有没有一种在Mathematica中剖析代码的好方法?我希望能够递减(即,如果我说f[a_] := b[a],那么Profile[f[1]]应该给出与Profile[b[1]]几乎相同的输出),但是我会解决能够执行诸如将Timing应用于每个相关子表达式的操作。这将是很好,如果我没有到特殊情况之类的东西Module,但我想,如Profile[Module[{x=1+2},x!]]给我像分析Mathematica代码

Time Expression   Result 
0  1     1 
0  2     2 
0  1 + 2    3 
0  x$1234    3 
0  x$1234 !   6 
0  Module[{x=1+2},x!] 6 

6 
+0

相关:http://stackoverflow.com/questions/3418892/profiling-memory-usage-in-mathematica – abcd

+0

另请参阅:http://stackoverflow.com/questions/4721171/performance-tuning-in-mathematica –

+0

所有:我试图用'TraceScan'来做到这一点,但我我遇到了Mathematica缓存结果的问题,因此,例如,对“Prime [13!]”的连续调用需要大不相同的时间进行评估。 –

回答

1

输出作为贝利萨留表明在回答我联系的问题以上,看起来是Wolfram Workbench includes a profiler。但是我不使用Workbench,所以我不能详细说明它的用途。

5

是的,Wolfram Workbench确实有一个分析器,尽管according to the documentation输出结果并不完全符合您的要求。

我应该注意到,Mr.Wizard在评论中提出的问题 - 缓存的结果会导致不同的计时结果 - 也可以应用于配置文件。

如果你想做一些只在数学,你可以尝试这样的:

myProfile[fun_Symbol,inputs_List]:= 
    TableForm[#[[{1,3,2}]]&/@ (Join @@@ ({Timing[f[#]],#} & /@ inputs))] 

如果你足够高兴有输出为{定时调整,输出,输入},而不是{时机,输入,输出}如您的问题中所述,您可以摆脱#[[{1,3,2}]]位。

编辑

因为我有工作台,这里就是一个例子。我有一个包AdvancedPlots其中包括一个功能CobwebPlot(是的,功能本身可以改善)。

CobwebPlot[x_?MatrixQ, opts___Rule] /; 
    And @@ (NumericQ /@ Flatten[x]) := 
Module[{n, \[Theta]s, numgrids, grids, struts, gridstyle, min, max, 
    data, labels, epilabels, pad}, 
    n = Length[First[x]]; 
    \[Theta]s = (2 \[Pi])/n Range[0, n] + If[OddQ[n], \[Pi]/2, 0]; 
    numgrids = 
    If[IntegerQ[#] && Positive[#], #, 
     NumberofGrids /. 
     Options[CobwebPlot] ] & @ (NumberofGrids /. {opts}); 
    {min, max} = {Min[#], Max[#]} &@ Flatten[x]; 
    gridstyle = GridStyle /. {opts} /. Options[CobwebPlot]; 
    pad = CobwebPadding /. {opts} /. Options[CobwebPlot]; 
    grids = 
    Outer[List, \[Theta]s, FindDivisions[{0, max + 1}, numgrids]]; 
    struts = Transpose[grids]; 
    labels = CobwebLabels /. {opts} /. Options[CobwebPlot]; 
    epilabels = 
    If[Length[labels] == n, 
    Thread[Text[ 
     labels, (1.2 max) Transpose[{Cos[Most[\[Theta]s]], 
     Sin[Most[\[Theta]s]]}]]], None]; 
    data = Map[Reverse, 
    Inner[List, Join[#, {First[#]}] & /@ x, \[Theta]s, List], {2}]; 
    Show[ListPolarPlot[grids, gridstyle, Joined -> True, Axes -> False, 
    PlotRangePadding -> pad], 
    ListPolarPlot[struts, gridstyle, Joined -> True, Axes -> False], 
    ListPolarPlot[data, 
    Sequence @@ FilterRules[{opts}, Options[ListPolarPlot]], 
    Sequence @@ 
    FilterRules[Options[CobwebPlot], Options[ListPolarPlot]], 
    Joined -> True, Axes -> None] , 
    If[Length[labels] == n, Graphics /@ epilabels, 
    Sequence @@ FilterRules[{opts}, Options[Graphics]] ]] 
    ] 

在调试模式下运行包

,然后运行该笔记本

enter image description here

提供了以下输出。

enter image description here

+0

如果你觉得这个功能可以改进,为什么不在Code Review上发布呢? –

+1

这几乎是我正在寻找的,但配置文件似乎错过了我的大部分代码。我正在尝试配置的代码现在需要63秒才能执行(根据Timing),但对配置文件的最大贡献是对MakeBox [Peak:PeakObject [_List],FormatType_]的90次调用,时间为\t 0.718(每个?总计?)和723344 \t调用7与0.655(每?总?)。此外,Profile [Do [100000 !, {100}]]在配置文件中根本没有提供任何条目。 –

4

这是使用TraceScan到评估的时间各个步骤的尝试。它使用原始AbsoluteTime[]三角洲,这可能是好的或坏的取决于你实际期望的时间。

确保在新的内核上运行这个例子,或Prime将缓存的结果,所有计时会〜= 0

t = AbsoluteTime[]; step = "start"; 

TraceScan[ 
    (Print[AbsoluteTime[] - t, " for ", step]; t = AbsoluteTime[]; step = #) &, 
    Module[{x = 7 + 7}, [email protected][x!]] 
] 
0.0010001 for start 

0.*10^-8 for Module[{x=7+7},Sqrt[Prime[x!]]] 

0.*10^-8 for Module 

0.*10^-8 for 7+7 

0.*10^-8 for Plus 

0.*10^-8 for 7 

0.*10^-8 for 7 

0.*10^-8 for 14 

0.*10^-8 for x$149=Unevaluated[14] 

0.*10^-8 for Set 

0.*10^-8 for x$149=14 

0.*10^-8 for 14 

0.*10^-8 for Sqrt[Prime[x$149!]] 

0.*10^-8 for Sqrt 

0.*10^-8 for Prime[x$149!] 

0.*10^-8 for Prime 

0.*10^-8 for x$149! 

0.*10^-8 for Factorial 

0.*10^-8 for x$149 

0.*10^-8 for 14 

0.*10^-8 for 14! 

0.*10^-8 for 87178291200 

2.6691526 for Prime[87178291200] 

0.*10^-8 for 2394322471421 

0.*10^-8 for Sqrt[2394322471421] 

0.*10^-8 for Sqrt[2394322471421] 

0.*10^-8 for Power 

0.*10^-8 for 2394322471421 

0.*10^-8 for 1/2