Профилирование Mathematica Code - PullRequest
12 голосов
/ 11 ноября 2011

Есть ли хороший способ профилировать код в Mathematica?Я хотел бы иметь возможность рекурсии (то есть, если я скажу f[a_] := b[a], то Profile[f[1]] должен дать почти такой же результат, как и Profile[b[1]]), но я позволю себе сделать что-то вроде применения Timingдля каждого соответствующего подвыражения.Было бы неплохо, если бы мне не нужно было что-то особенное, например, 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

Ответы [ 3 ]

5 голосов
/ 11 ноября 2011

Да, Wolfram Workbench действительно имеет профилировщик, хотя согласно документации вывод не совсем в той форме, которую вы хотите.

Я должен отметить, что проблема, поднятая Mr.Wizard в комментариях - что кэшированные результаты приведут к различным результатам синхронизации - также может применяться в профиле.

Если вы хотите сделать что-то исключительно в Mathematica, вы можете попробовать что-то вроде:

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

Если бы вы были достаточно счастливы иметь вывод как {синхронизация, вывод, ввод}, а не {синхронизация, ввод, вывод}, как указано в вашем вопросе, вы могли бы избавиться от бита #[[{1,3,2}]].

EDIT

Так как у меня есть Workbench, вот пример. У меня есть пакет 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

4 голосов
/ 11 ноября 2011

Это попытка использовать TraceScan для определения времени отдельных этапов оценки. Он использует AbsoluteTime[] дельты, которые могут быть хорошими или плохими в зависимости от того, что вы на самом деле ожидаете.

Обязательно запустите этот пример на новом ядре, или Prime будет кешировать его результаты, и все значения времени будут ~ = 0.

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
1 голос
/ 11 ноября 2011

Как показал Велисарий в ответ на вопрос, который я упомянул выше, Wolfram Workbench включает профилировщик .Однако я не использую Workbench, поэтому не могу подробно описать его использование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...