mtx-profile.lua /size: 7011 b    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
mtx-profile
'
]
=
{
2
version
=
1
.
000
,
3
comment
=
"
companion to mtxrun.lua
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
-- todo: also line number
10
-- todo: sort runtime as option
11
-- todo: make it more efficient .. real old code
12 13
local
match
,
format
,
find
,
gsub
=
string
.
match
,
string
.
format
,
string
.
find
,
string
.
gsub
14 15
local
helpinfo
=
[[
16<?xml version="1.0"?> 17<application> 18 <metadata> 19 <entry name="name">mtx-profile</entry> 20 <entry name="detail">ConTeXt MkIV LuaTeX Profiler</entry> 21 <entry name="version">1.00</entry> 22 </metadata> 23 <flags> 24 <category name="basic"> 25 <subcategory> 26 <flag name="analyze"><short>analyze lua calls</short></flag> 27 <flag name="trace"><short>analyze tex calls</short></flag> 28 </subcategory> 29 </category> 30 </flags> 31</application> 32
]]
33 34
local
application
=
logs
.
application
{
35
name
=
"
mtx-profile
"
,
36
banner
=
"
ConTeXt MkIV LuaTeX Profiler 1.00
"
,
37
helpinfo
=
helpinfo
,
38
}
39 40
local
report
=
application
.
report
41 42
scripts
=
scripts
or
{
}
43
scripts
.
profiler
=
scripts
.
profiler
or
{
}
44 45
local
timethreshold
=
0
46
local
callthreshold
=
2500
47
local
countthreshold
=
2500
48 49
local
functiontemplate
=
"
%12s %03.4f %9i %s
"
50
local
calltemplate
=
"
%9i %s
"
51
local
totaltemplate
=
"
%i internal calls, %i function calls taking %3.4f seconds
"
52
local
thresholdtemplate
=
"
thresholds: %i internal calls, %i function calls, %i seconds
"
53 54
function
scripts
.
profiler
.
analyze
(
filename
)
55
local
f
=
io
.
open
(
filename
)
56
if
f
then
57
local
times
,
counts
,
calls
=
{
}
,
{
}
,
{
}
58
local
totalruntime
,
totalcount
,
totalcalls
=
0
,
0
,
0
59
for
line
in
f
:
lines
(
)
do
60
if
not
find
(
line
,
"
__index
"
)
and
not
find
(
line
,
"
__newindex
"
)
then
61
local
stacklevel
,
filename
,
functionname
,
linenumber
,
currentline
,
localtime
,
totaltime
=
match
(
line
,
"
^(%d+)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)
"
)
62
if
not
filename
then
63
-- next
64
elseif
filename
=
=
"
=[C]
"
then
65
if
not
functionname
:
find
(
"
^%(
"
)
then
66
calls
[
functionname
]
=
(
calls
[
functionname
]
or
0
)
+
1
67
end
68
else
69
local
filename
=
match
(
filename
,
"
^@(.*)$
"
)
70
if
filename
then
71
local
fi
=
times
[
filename
]
72
if
not
fi
then
fi
=
{
}
times
[
filename
]
=
fi
end
73
fi
[
functionname
]
=
(
fi
[
functionname
]
or
0
)
+
tonumber
(
localtime
)
74
counts
[
functionname
]
=
(
counts
[
functionname
]
or
0
)
+
1
75
end
76
end
77
end
78
end
79
f
:
close
(
)
80
print
(
"
"
)
81
local
loaded
=
{
}
82
local
sorted
=
table
.
sortedkeys
(
times
)
83
for
i
=
1
,
#
sorted
do
84
local
filename
=
sorted
[
i
]
85
local
functions
=
times
[
filename
]
86
local
sorted
=
table
.
sortedkeys
(
functions
)
87
for
i
=
1
,
#
sorted
do
88
local
functionname
=
sorted
[
i
]
89
local
totaltime
=
functions
[
functionname
]
90
local
count
=
counts
[
functionname
]
91
totalcount
=
totalcount
+
count
92
if
totaltime
>
timethreshold
or
count
>
countthreshold
then
93
totalruntime
=
totalruntime
+
totaltime
94
local
functionfile
,
somenumber
=
match
(
functionname
,
"
^@(.+):(.-)$
"
)
95
if
functionfile
then
96
local
number
=
tonumber
(
somenumber
)
97
if
number
then
98
if
not
loaded
[
functionfile
]
then
99
loaded
[
functionfile
]
=
string
.
splitlines
(
io
.
loaddata
(
functionfile
)
or
"
"
)
100
end
101
functionname
=
loaded
[
functionfile
]
[
number
]
or
functionname
102
functionname
=
gsub
(
functionname
,
"
^%s*
"
,
"
"
)
103
functionname
=
gsub
(
functionname
,
"
%s*%-%-.*$
"
,
"
"
)
104
functionname
=
number
.
.
"
:
"
.
.
functionname
105
end
106
end
107
filename
=
file
.
basename
(
filename
)
108
print
(
format
(
functiontemplate
,
filename
,
totaltime
,
count
,
functionname
)
)
109
end
110
end
111
end
112
print
(
"
"
)
113
local
sorted
=
table
.
sortedkeys
(
calls
)
114
for
i
=
1
,
#
sorted
do
115
local
call
=
sorted
[
i
]
116
local
n
=
calls
[
call
]
117
totalcalls
=
totalcalls
+
n
118
if
n
>
callthreshold
then
119
print
(
calltemplate
:
format
(
n
,
call
)
)
120
end
121
end
122
print
(
"
"
)
123
print
(
totaltemplate
:
format
(
totalcalls
,
totalcount
,
totalruntime
)
)
124
print
(
"
"
)
125
print
(
thresholdtemplate
:
format
(
callthreshold
,
countthreshold
,
timethreshold
)
)
126
end
127
end
128 129
function
scripts
.
profiler
.
x_analyze
(
filename
)
130
local
f
=
io
.
open
(
filename
)
131
local
calls
=
{
}
132
local
lines
=
0
133
if
f
then
134
while
true
do
135
local
line
=
f
:
read
(
)
136
if
line
then
137
lines
=
lines
+
1
138
local
c
=
match
(
line
,
"
\\([a-zA-Z%!%?@]+) *%->
"
)
139
if
c
then
140
local
cc
=
calls
[
c
]
141
if
not
cc
then
142
calls
[
c
]
=
1
143
else
144
calls
[
c
]
=
cc
+
1
145
end
146
end
147
else
148
break
149
end
150
end
151
f
:
close
(
)
152
local
noc
=
0
153
local
criterium
=
100
154
for
name
,
n
in
next
,
calls
do
155
if
n
>
criterium
then
156
if
find
(
name
,
"
^@@[a-z][a-z]
"
)
then
157
-- parameter
158
elseif
find
(
name
,
"
^[cvserft]%!
"
)
then
159
-- variables and constants
160
elseif
find
(
name
,
"
^%?%?[a-z][a-z]$
"
)
then
161
-- prefix
162
elseif
find
(
name
,
"
^%!%!
"
)
then
163
-- reserved
164
elseif
find
(
name
,
"
^@.+@$
"
)
then
165
-- weird
166
else
167
noc
=
noc
+
n
168
print
(
format
(
"
%6i: %s
"
,
n
,
name
)
)
169
end
170
end
171
end
172
print
(
"
"
)
173
print
(
format
(
"
number of lines: %s
"
,
lines
)
)
174
print
(
format
(
"
number of calls: %s
"
,
noc
)
)
175
print
(
format
(
"
criterium calls: %s
"
,
criterium
)
)
176
end
177
end
178 179
--~ scripts.profiler.analyze("t:/manuals/mk/mk-fonts-profile.lua")
180
--~ scripts.profiler.analyze("t:/manuals/mk/mk-introduction-profile.lua")
181 182
if
environment
.
argument
(
"
analyze
"
)
then
183
scripts
.
profiler
.
analyze
(
environment
.
files
[
1
]
or
"
luatex-profile.log
"
)
184
elseif
environment
.
argument
(
"
trace
"
)
then
185
scripts
.
profiler
.
analyze
(
environment
.
files
[
1
]
or
"
temp.log
"
)
186
elseif
environment
.
argument
(
"
exporthelp
"
)
then
187
application
.
export
(
environment
.
argument
(
"
exporthelp
"
)
,
environment
.
files
[
1
]
)
188
else
189
application
.
help
(
)
190
end
191