Last active
December 20, 2015 07:59
-
-
Save Tehnix/6096904 to your computer and use it in GitHub Desktop.
Benchmarking of several list construction methods with filtering applied.
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
import time | |
import itertools | |
def test_results(tests, times_to_run_tests, *args): | |
# Fetch the results and save the value of the fastest function | |
fastest = None | |
results = [] | |
for fn in tests: | |
name = "" | |
res = 0 | |
for i in range(times_to_run_tests): | |
test = fn(*args) | |
res += test["time"] | |
name = test["name"] | |
avg = res / times_to_run_tests | |
results.append({"average": avg, "name": name}) | |
print "| {0: <20} | {1: >12} | {2: >18} s | {3: >23} % |".format( | |
name, times_to_run_tests, avg, "???" | |
) | |
if fastest is None or avg < fastest: | |
fastest = avg | |
# Print the table of results | |
header = "| {0: <20} | {1: <12} | {2: <20} | {3: <25} |".format( | |
"Function name", "Times tested", "Average running time", "Speed compared to fastest" | |
) | |
separator = "+" + ("-" * (len(header) - 2)) + "+" | |
print separator | |
print header | |
print separator | |
for result in sorted(results, key=lambda x: x["average"]): | |
print "| {0: <20} | {1: >12} | {2: >18} s | {3: >23} % |".format( | |
result["name"], times_to_run_tests, result["average"], round((result["average"] / fastest * 100), 2) | |
) | |
print separator | |
def test_it(fn): | |
"""Decorator to return function info and time results.""" | |
def testing(*args): | |
name = fn.__name__ | |
doc_string = fn.__doc__ | |
start = time.time() | |
fn(*args) | |
total_time = round((time.time() - start), 5) | |
return {"name": name, "description": doc_string, "time": total_time} | |
return testing | |
@test_it | |
def list_comprehension(particles): | |
"""Use a list comprehension to filter the objects in the particles list.""" | |
l = [x for x in particles if not x.dead and (x.on_step() or True)] | |
@test_it | |
def filter_lambda(particles): | |
"""Use the filter function with a lambda to filter the objects in the particles list.""" | |
l = filter(lambda x: not x.dead and (x.on_step() or True), particles) | |
@test_it | |
def filter_function(particles): | |
"""Use the filter function with a predefined checking function to filter the objects in the particles list.""" | |
def check(x): | |
if not x.dead: | |
x.on_step() | |
return True | |
return False | |
l = filter(check, particles) | |
@test_it | |
def itertools_ifilter(particles): | |
"""Use itertools.ifilter to filter and construct a new list from the particles list.""" | |
l = [] | |
for particle in itertools.ifilter(lambda x: not x.dead and (x.on_step() or True), particles): | |
l.append(particle) | |
class Particle(object): | |
def __init__(self): | |
self.dead = False | |
def on_step(self): | |
pass | |
list_size = 10000000 | |
particles = [] | |
for i in range(list_size): | |
p = Particle() | |
particles.append(p) | |
print "Done constructing list, performing tests..." | |
tests = [ | |
list_comprehension, | |
filter_lambda, | |
filter_function, | |
itertools_ifilter | |
] | |
test_results(tests, 5, particles) | |
# +----------------------------------------------------------------------------------------+ | |
# | Function name | Times tested | Average running time | Speed compared to fastest | | |
# +----------------------------------------------------------------------------------------+ | |
# | list_comprehension | 5 | 3.31077 s | 100.0 % | | |
# | filter_function | 5 | 3.373938 s | 101.91 % | | |
# | filter_lambda | 5 | 3.442364 s | 103.97 % | | |
# | itertools_ifilter | 5 | 5.619166 s | 169.72 % | | |
# +----------------------------------------------------------------------------------------+ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment