1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
(* Copyright (C) 2010 Ian Hinder and Barry Wardell *)
BeginPackage["Profile`"];
Profile;
ProfileTime;
ProfileCount;
ClearProfile;
Timer;
GetTimers;
RemoveTimers;
ThresholdTimers;
PrintTimerTree;
CoalesceTimers;
Begin["`Private`"];
ClearProfile[] :=
Module[{},
Clear[ProfileTime];
Clear[ProfileCount]];
SetAttributes[Profile, HoldAll];
Profile[name_, code_] :=
Module[{time, result, name2, result2, subTimers},
name2 = Evaluate[name];
{result2,subTimers} = Reap[{time, result} = AbsoluteTiming[ReleaseHold[code]]];
If[Head[ProfileTime[name2]] === ProfileTime, ProfileTime[name2] = 0.0];
If[Head[ProfileCount[name2]] === ProfileCount, ProfileCount[name2] = 0];
ProfileTime[name2] += time;
ProfileCount[name2] += 1;
Sow[Timer[name2,time,If[subTimers === {}, {}, subTimers[[1]]]]];
result];
(* Profile[n_, x_] := x; *)
(* The code below is a prototype for handling a tree of timer
information from Profile. It needs to be tidied up and a good
interface defined. Example of use:
{result, timers} = Reap@MyProfile["Total", <code>];
treeView@addUntimed@
Timer[timers[[1, 1, 1]], timers[[1, 1, 2]],
addTimers[timers[[1, 1, 3]], sameq, plus]]
*)
treeView[t : Timer[n_, v_, c_]] :=
Module[{},
If[c === {},
Row[{" ", v, " ", n}],
OpenerView[{Row[{v, " ", n}],
Column[treeView /@ c]}, True]]]
(* Take a list and, for all the members which are "sameq" as each \
other, replace them with the application of "plus" to them *)
add[l_, sameq_, plus_] :=
Map[plus, Gather[l, sameq]];
addTimers[ts_List, sameq_, plus_] :=
add[Map[Timer[#[[1]], #[[2]], addTimers[#[[3]], sameq, plus]] &, ts],
sameq, plus];
sameq[Timer[n1_, v1_, s1_], Timer[n2_, v2_, s2_]] :=
n1 === n2 && Length[s1] == Length[s2] &&
And @@ MapThread[sameq, {s1, s2}];
plus[ts_List] :=
Timer[ts[[1, 1]], Plus @@ Map[#[[2]] &, ts],
MapThread[plus[{##}] &, Map[#[[3]] &, ts]]];
addUntimed[Timer[n_, v_, s_List]] :=
If[Length[s] === 0, Timer[n, v, s],
Module[{total},
total = Plus @@ Map[#[[2]] &, s];
Timer[n, v,
Append[Map[addUntimed, s], Timer["untimed", v - total, {}]]]]];
SetAttributes[GetTimers, HoldAll];
GetTimers[expr_] :=
Module[
{result,timers},
{result,timers} = Reap[Profile["Total", expr]];
{result, timers[[1,1]]}];
CoalesceTimers[t_Timer] :=
addTimers[{t}, sameq, plus][[1]];
(* GetTimers[expr_] := *)
(* addUntimed[ *)
(* Timer[timers[[1, 1, 1]], timers[[1, 1, 2]], *)
(* addTimers[timers[[1, 1, 3]], sameq, plus]]]; *)
RemoveTimers[timers_, remove_List] :=
timers //. Table[Timer[name, _, {sub___}] :> sub, {name, remove}];
ThresholdTimers[t:Timer[name_, value_, sub_], threshold_:0.1] :=
thresholdTimers[t, threshold*value];
thresholdTimers[t:Timer[name_, value_, sub_], absThreshold_] :=
DeleteCases[t, Timer[n_, v_, s_] /; v < absThreshold, Infinity] /.
Timer[tt_,v_,{Timer["untimed",_,{}]}] :> Timer[tt,v,{}];
PrintTimerTree[Timer[name_, value_, sub_], indent_:0] :=
Module[
{},
Print[StringJoin@@ConstantArray["| ", indent],"o",PaddedForm[value,{3,2}], " ", name];
Map[PrintTimerTree[#, indent+1]&, sub]];
End[];
EndPackage[];
|