Wolfram mathematica 剖析Mathematica代码

Wolfram mathematica 剖析Mathematica代码,wolfram-mathematica,profiling,Wolfram Mathematica,Profiling,在Mathematica中有没有一个好的方法来分析代码?我希望能够递归(也就是说,如果我说f[a\u]:=b[a],那么Profile[f[1]]应该给出与Profile[b[1]]几乎相同的输出,但我会满足于能够对每个相关的子表达式应用计时。如果我不需要像Module这样的特殊情况,那就太好了,但是我想,例如,Profile[Module[{x=1+2},x!]给我一个如下输出 Time Expression Result 0 1

在Mathematica中有没有一个好的方法来分析代码?我希望能够递归(也就是说,如果我说
f[a\u]:=b[a]
,那么
Profile[f[1]]
应该给出与
Profile[b[1]]
几乎相同的输出,但我会满足于能够对每个相关的子表达式应用
计时。如果我不需要像
Module
这样的特殊情况,那就太好了,但是我想,例如,
Profile[Module[{x=1+2},x!]
给我一个如下输出

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

正如belisarius在回答我上面链接的问题时所显示的那样,似乎是这样的。但是,我不使用Workbench,因此我无法详细说明它的用法。

是的,Wolfram Workbench确实有一个分析器,尽管输出的形式与您想要的不完全相同

我应该注意到Wizard先生在评论中提出的问题——缓存结果将导致不同的计时结果——也可以应用于profile

如果你想专门在Mathematica做一些事情,你可以尝试以下方法:

myProfile[fun_Symbol,inputs_List]:=  
    TableForm[#[[{1,3,2}]]&/@ (Join @@@ ({Timing[f[#]],#} & /@ inputs))]
如果您很高兴将输出设置为{timing,output,input},而不是问题中指定的{timing,input,output},那么可以去掉
#[[{1,3,2}]

编辑

因为我有一个工作台,下面是一个例子。我有一个包
AdvancedPlots
,其中包含一个函数
CobwebPlot
(是的,函数本身可以改进)

在调试模式下运行包

然后运行这个笔记本

给出以下输出


这是一种尝试,使用
TraceScan
为评估的各个步骤计时。它使用原始的
AbsoluteTime[]
delta,它的好坏取决于您对时间的实际期望

请确保在新内核上运行此示例,否则
Prime
将缓存其结果,并且所有计时将为~=0

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

TraceScan[
  (Print[AbsoluteTime[] - t, " for ", step]; t = AbsoluteTime[]; step = #) &,
  Module[{x = 7 + 7}, Sqrt@Prime[x!]]
]
0.0010001表示启动 0.*10^-8表示模块[{x=7+7},Sqrt[Prime[x!]] 模块0.*10^-8 0.*10^-8代表7+7 0.*10^-8表示加号 0.*10^-8代表7 0.*10^-8代表7 0.*10^-8分14秒 0.*10^-8 x$149=未估价[14] 0.*10^-8套 0.*10^-8 x$149=14 0.*10^-8分14秒 0.*10^-8用于Sqrt[Prime[x$149!]] 0.*10^-8用于Sqrt 0.*10^-8为优质[x$149!] 0.*10^-8表示基本值 0.*10^-8 x$149! 0.*10^-8表示阶乘 0.*10^-8 x$149 0.*10^-8分14秒 0.*10^-8分14秒! 0.*10^-8用于87178291200 2.6691526,主要用于[87178291200] 0.*10^-8用于2394322471421 0.*10^-8用于Sqrt[2394322471421] 0.*10^-8用于Sqrt[2394322471421] 0.*10^-8表示电源 0.*10^-8用于2394322471421
0.*10^-8 for 1/2Related:另请参见:All:我正在尝试使用
TraceScan
执行此操作,但我遇到了Mathematica缓存结果的问题,因此,例如,顺序调用
Prime[13!]
需要非常不同的时间进行计算。如果您觉得此函数可以改进,为什么不把它发布在代码审查上呢?这几乎就是我想要的,但配置文件似乎遗漏了我的大部分代码。我现在试图分析的代码执行时间为63秒(根据时间),但对分析的最大贡献是90次调用MakeBoxs[Peak:PeakObject[List],FormatType],每次调用时间为0.718(总计?),723344次调用7次,每次调用时间为0.655(总计?)。此外,Profile[Do[100000!,{100}]]之类的东西根本不会在Profile中提供任何条目。
t = AbsoluteTime[]; step = "start";

TraceScan[
  (Print[AbsoluteTime[] - t, " for ", step]; t = AbsoluteTime[]; step = #) &,
  Module[{x = 7 + 7}, Sqrt@Prime[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