Created
March 8, 2017 10:53
-
-
Save pestilence669/5f8e684370dcc1b8e2e79c81de8181d9 to your computer and use it in GitHub Desktop.
Simple Python benchmark rig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# vim: set ts=4 sw=4 et fileencoding=utf-8: | |
# | |
# Simple benchmark & testing rig to play with finding the fastest methods when | |
# searching for the first value in a sequence, determined by a predicate. This | |
# file uses: lambda x: x / 2 == target | |
# | |
from __future__ import print_function | |
from inspect import getmembers, isfunction | |
from itertools import ifilter | |
import sys | |
import timeit | |
ITERATIONS = 1000 | |
target, haystack = 669, range(669 * 4) | |
def test_next_with_a_generator(): | |
'''next(predicate, None)''' | |
return next((needle for needle in haystack if needle / 2 == target), None) | |
def test_next_with_an_iterator_filter(): | |
'''next(ifilter(predicate), None)''' | |
return next(ifilter(lambda needle: needle / 2 == target, haystack), None) | |
def test_basic_pythonic_loop(): | |
'''for needle in haystack: # ...''' | |
for needle in haystack: | |
if needle / 2 == target: | |
return needle | |
def test_while_loop_forward(): | |
'''while i < len(haystack):''' | |
i = 0 | |
while i < len(haystack): | |
if haystack[i] / 2 == target: | |
return haystack[i] | |
i += 1 | |
def test_while_loop_forward_with_cached_len(): | |
'''while i < len(haystack):''' | |
i = 0 | |
s = len(haystack) | |
while i < s: | |
if haystack[i] / 2 == target: | |
return haystack[i] | |
i += 1 | |
def test_while_loop_backward(): | |
'''while i >= 0:''' | |
i = len(haystack) - 1 # go backward to avoid len(), which has a cost | |
while i >= 0: | |
if haystack[i] / 2 == target: | |
return haystack[i] | |
i -= 1 | |
def test_filter_with_full_traversal(): | |
'''filter(predicate, haystack)[0]''' | |
return filter(lambda needle: needle / 2 == target, haystack)[0] | |
############################################################################### | |
if __name__ == '__main__': | |
all_funcs = getmembers(sys.modules[__name__], isfunction) | |
run_funcs = (f for nm, f in sorted(all_funcs) if nm.startswith('test_')) | |
results = [] | |
for i, f in enumerate(run_funcs): | |
print('#' * 80) | |
print('Test #%d (%s) - %s' % (i, f.__name__, f.__doc__)) | |
command = 'assert(%s() / 2 == target)' % f.__name__ | |
setup = 'from __main__ import %s, target' % f.__name__ | |
duration = timeit.timeit(command, setup=setup, number=ITERATIONS) | |
results.append((duration, f.__name__)) | |
print('Duration: %fs' % duration) | |
print('#' * 80) | |
print('SUMMARY:') | |
print('\tDURATION\tWORSE\tTEST NAME') | |
min_duration = min(d for d, n in results) | |
for duration, name in sorted(results): | |
pct = (duration / min_duration - 1) * 100.0 | |
print('\t%fs\t%f%%\t%s' % (duration, pct, name)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment