blob: 634e41b142e6d3a93671411ec271f0b123a4e4da (
plain)
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
|
________________________________________________________________________
PYBENCH - A Python Benchmark Suite
________________________________________________________________________
Extendable suite of of low-level benchmarks for measuring
the performance of the Python implementation
(interpreter, compiler or VM).
pybench is a collection of tests that provides a standardized way to
measure the performance of Python implementations. It takes a very
close look at different aspects of Python programs and let's you
decide which factors are more important to you than others, rather
than wrapping everything up in one number, like the other performance
tests do (e.g. pystone which is included in the Python Standard
Library).
pybench has been used in the past by several Python developers to
track down performance bottlenecks or to demonstrate the impact of
optimizations and new features in Python.
The command line interface for pybench is the file pybench.py. Run
this script with option '--help' to get a listing of the possible
options. Without options, pybench will simply execute the benchmark
and then print out a report to stdout.
Micro-Manual
------------
Run 'pybench.py -h' to see the help screen.
Run 'pybench.py' to just let the benchmark suite do it's thing and
'pybench.py -f <file>' to have it store the results in a file too.
This is the current output of pybench.py --help:
Synopsis:
pybench.py [option] files...
Options and default settings:
-n arg number of rounds (10)
-f arg save benchmark to file arg ()
-c arg compare benchmark with the one in file arg ()
-s arg show benchmark in file arg, then exit ()
-S show statistics of benchmarks (0)
-w arg set warp factor to arg (20)
-d hide noise in compares (0)
--no-gc disable garbage collection (0)
-v generate verbose output
-h show this help text
--help show this help text
--debug enable debugging
--copyright show copyright
--examples show examples of usage
Version:
1.3
The normal operation is to run the suite and display the
results. Use -f to save them for later reuse or comparisms.
Examples:
python1.5 pybench.py -w 100 -f p15
python1.4 pybench.py -w 100 -f p14
python pybench.py -s p15 -c p14
License
-------
See LICENSE file.
Sample output
-------------
PYBENCH 1.3
Machine Details:
Platform ID: Linux-2.6.8-24.19-default-x86_64-with-SuSE-9.2-x86-64
Executable: /home/lemburg/projects/Python/Installation/bin/python
Python: 2.5a1.0
Compiler: GCC 3.3.4 (pre 3.3.5 20040809)
Build: Apr 9 2006 01:50:57 (#trunk)
Searching for tests...
BuiltinFunctionCalls
BuiltinMethodLookup
CompareFloats
CompareFloatsIntegers
CompareIntegers
CompareInternedStrings
CompareLongs
CompareStrings
CompareUnicode
ConcatStrings
ConcatUnicode
CreateInstances
CreateStringsWithConcat
CreateUnicodeWithConcat
DictCreation
DictWithFloatKeys
DictWithIntegerKeys
DictWithStringKeys
ForLoops
IfThenElse
ListSlicing
NestedForLoops
NormalClassAttribute
NormalInstanceAttribute
PythonFunctionCalls
PythonMethodCalls
Recursion
SecondImport
SecondPackageImport
SecondSubmoduleImport
SimpleComplexArithmetic
SimpleDictManipulation
SimpleFloatArithmetic
SimpleIntFloatArithmetic
SimpleIntegerArithmetic
SimpleListManipulation
SimpleLongArithmetic
SmallLists
SmallTuples
SpecialClassAttribute
SpecialInstanceAttribute
StringMappings
StringPredicates
StringSlicing
TryExcept
TryRaiseExcept
TupleSlicing
UnicodeMappings
UnicodePredicates
UnicodeProperties
UnicodeSlicing
Running 10 round(s) of the suite:
...
Round 10 real abs overhead
BuiltinFunctionCalls: 0.030r 0.030a 0.000o
BuiltinMethodLookup: 0.059r 0.060a 0.001o
CompareFloats: 0.050r 0.050a 0.000o
CompareFloatsIntegers: 0.050r 0.050a 0.000o
CompareIntegers: 0.070r 0.070a 0.000o
CompareInternedStrings: 0.039r 0.040a 0.001o
CompareLongs: 0.050r 0.050a 0.000o
CompareStrings: 0.060r 0.060a 0.000o
CompareUnicode: 0.060r 0.060a 0.000o
ConcatStrings: 0.040r 0.040a 0.000o
ConcatUnicode: 0.050r 0.050a 0.000o
CreateInstances: 0.050r 0.050a 0.000o
CreateStringsWithConcat: 0.029r 0.030a 0.001o
CreateUnicodeWithConcat: 0.060r 0.060a 0.000o
DictCreation: 0.040r 0.040a 0.000o
DictWithFloatKeys: 0.089r 0.090a 0.000o
DictWithIntegerKeys: 0.059r 0.060a 0.001o
DictWithStringKeys: 0.070r 0.070a 0.001o
ForLoops: 0.050r 0.050a 0.000o
IfThenElse: 0.070r 0.070a 0.000o
ListSlicing: 0.030r 0.030a 0.000o
NestedForLoops: 0.030r 0.030a 0.000o
NormalClassAttribute: 0.060r 0.060a 0.000o
NormalInstanceAttribute: 0.060r 0.060a 0.000o
PythonFunctionCalls: 0.060r 0.060a 0.000o
PythonMethodCalls: 0.050r 0.050a 0.000o
Recursion: 0.050r 0.050a 0.000o
SecondImport: 0.030r 0.030a 0.000o
SecondPackageImport: 0.030r 0.030a 0.000o
SecondSubmoduleImport: 0.040r 0.040a 0.000o
SimpleComplexArithmetic: 0.030r 0.030a 0.000o
SimpleDictManipulation: 0.040r 0.040a 0.000o
SimpleFloatArithmetic: 0.050r 0.050a 0.001o
SimpleIntFloatArithmetic: 0.060r 0.060a 0.000o
SimpleIntegerArithmetic: 0.060r 0.060a 0.000o
SimpleListManipulation: 0.030r 0.030a 0.000o
SimpleLongArithmetic: 0.030r 0.030a 0.000o
SmallLists: 0.050r 0.050a 0.000o
SmallTuples: 0.050r 0.050a 0.000o
SpecialClassAttribute: 0.060r 0.060a 0.000o
SpecialInstanceAttribute: 0.079r 0.080a 0.001o
StringMappings: 0.060r 0.060a 0.000o
StringPredicates: 0.049r 0.050a 0.001o
StringSlicing: 0.039r 0.040a 0.000o
TryExcept: 0.079r 0.080a 0.001o
TryRaiseExcept: 0.059r 0.060a 0.001o
TupleSlicing: 0.050r 0.050a 0.000o
UnicodeMappings: 0.070r 0.070a 0.001o
UnicodePredicates: 0.059r 0.060a 0.001o
UnicodeProperties: 0.059r 0.060a 0.001o
UnicodeSlicing: 0.050r 0.050a 0.000o
----------------------
Average round time: 2.937 seconds
Tests: per run per oper. overhead
------------------------------------------------------------------------
BuiltinFunctionCalls: 29.85 ms 0.23 us 0.00 ms
BuiltinMethodLookup: 66.85 ms 0.13 us 0.50 ms
CompareFloats: 43.00 ms 0.10 us 0.00 ms
CompareFloatsIntegers: 51.80 ms 0.12 us 0.00 ms
CompareIntegers: 70.70 ms 0.08 us 0.50 ms
CompareInternedStrings: 41.40 ms 0.08 us 0.50 ms
CompareLongs: 47.90 ms 0.11 us 0.00 ms
CompareStrings: 58.50 ms 0.12 us 0.50 ms
CompareUnicode: 56.55 ms 0.15 us 0.50 ms
ConcatStrings: 44.75 ms 0.30 us 0.00 ms
ConcatUnicode: 54.55 ms 0.36 us 0.50 ms
CreateInstances: 50.95 ms 1.21 us 0.00 ms
CreateStringsWithConcat: 28.85 ms 0.14 us 0.50 ms
CreateUnicodeWithConcat: 53.75 ms 0.27 us 0.00 ms
DictCreation: 41.90 ms 0.28 us 0.00 ms
DictWithFloatKeys: 88.50 ms 0.15 us 0.50 ms
DictWithIntegerKeys: 62.55 ms 0.10 us 0.50 ms
DictWithStringKeys: 60.50 ms 0.10 us 0.50 ms
ForLoops: 46.90 ms 4.69 us 0.00 ms
IfThenElse: 60.55 ms 0.09 us 0.00 ms
ListSlicing: 29.90 ms 8.54 us 0.00 ms
NestedForLoops: 33.95 ms 0.10 us 0.00 ms
NormalClassAttribute: 62.75 ms 0.10 us 0.50 ms
NormalInstanceAttribute: 61.80 ms 0.10 us 0.50 ms
PythonFunctionCalls: 60.00 ms 0.36 us 0.00 ms
PythonMethodCalls: 50.00 ms 0.67 us 0.00 ms
Recursion: 46.85 ms 3.75 us 0.00 ms
SecondImport: 35.00 ms 1.40 us 0.00 ms
SecondPackageImport: 32.00 ms 1.28 us 0.00 ms
SecondSubmoduleImport: 38.00 ms 1.52 us 0.00 ms
SimpleComplexArithmetic: 26.85 ms 0.12 us 0.00 ms
SimpleDictManipulation: 40.85 ms 0.14 us 0.00 ms
SimpleFloatArithmetic: 48.70 ms 0.09 us 0.50 ms
SimpleIntFloatArithmetic: 57.70 ms 0.09 us 0.00 ms
SimpleIntegerArithmetic: 58.75 ms 0.09 us 0.50 ms
SimpleListManipulation: 34.80 ms 0.13 us 0.00 ms
SimpleLongArithmetic: 30.95 ms 0.19 us 0.50 ms
SmallLists: 47.60 ms 0.19 us 0.00 ms
SmallTuples: 48.80 ms 0.20 us 0.50 ms
SpecialClassAttribute: 61.70 ms 0.10 us 0.00 ms
SpecialInstanceAttribute: 76.70 ms 0.13 us 0.50 ms
StringMappings: 58.70 ms 0.47 us 0.00 ms
StringPredicates: 50.00 ms 0.18 us 1.00 ms
StringSlicing: 39.65 ms 0.23 us 0.50 ms
TryExcept: 84.45 ms 0.06 us 0.50 ms
TryRaiseExcept: 61.75 ms 4.12 us 0.50 ms
TupleSlicing: 48.95 ms 0.47 us 0.00 ms
UnicodeMappings: 71.50 ms 3.97 us 0.50 ms
UnicodePredicates: 52.75 ms 0.23 us 1.00 ms
UnicodeProperties: 61.90 ms 0.31 us 1.00 ms
UnicodeSlicing: 53.75 ms 0.31 us 0.50 ms
------------------------------------------------------------------------
Average round time: 2937.00 ms
________________________________________________________________________
Writing New Tests
________________________________________________________________________
pybench tests are simple modules defining one or more pybench.Test
subclasses.
Writing a test essentially boils down to providing two methods:
.test() which runs .rounds number of .operations test operations each
and .calibrate() which does the same except that it doesn't actually
execute the operations.
Here's an example:
------------------
from pybench import Test
class IntegerCounting(Test):
# Version number of the test as float (x.yy); this is important
# for comparisons of benchmark runs - tests with unequal version
# number will not get compared.
version = 1.0
# The number of abstract operations done in each round of the
# test. An operation is the basic unit of what you want to
# measure. The benchmark will output the amount of run-time per
# operation. Note that in order to raise the measured timings
# significantly above noise level, it is often required to repeat
# sets of operations more than once per test round. The measured
# overhead per test round should be less than 1 second.
operations = 20
# Number of rounds to execute per test run. This should be
# adjusted to a figure that results in a test run-time of between
# 20-50 seconds.
rounds = 100000
def test(self):
""" Run the test.
The test needs to run self.rounds executing
self.operations number of operations each.
"""
# Init the test
a = 1
# Run test rounds
#
# NOTE: Use xrange() for all test loops unless you want to face
# a 20MB process !
#
for i in xrange(self.rounds):
# Repeat the operations per round to raise the run-time
# per operation significantly above the noise level of the
# for-loop overhead.
# Execute 20 operations (a += 1):
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
a += 1
def calibrate(self):
""" Calibrate the test.
This method should execute everything that is needed to
setup and run the test - except for the actual operations
that you intend to measure. pybench uses this method to
measure the test implementation overhead.
"""
# Init the test
a = 1
# Run test rounds (without actually doing any operation)
for i in xrange(self.rounds):
# Skip the actual execution of the operations, since we
# only want to measure the test's administration overhead.
pass
Registering a new test module
-----------------------------
To register a test module with pybench, the classes need to be
imported into the pybench.Setup module. pybench will then scan all the
symbols defined in that module for subclasses of pybench.Test and
automatically add them to the benchmark suite.
Have fun,
--
Marc-Andre Lemburg
mal@lemburg.com
|