2011-11-11 117 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