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