Skip to content

Instantly share code, notes, and snippets.

@zed
Created September 23, 2009 22:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zed/192338 to your computer and use it in GitHub Desktop.
Save zed/192338 to your computer and use it in GitHub Desktop.
"""Measure relative performance of answers to [1].
[1] http://stackoverflow.com/questions/1456617
"""
import linecache
import random
from timeit import default_timer
WORDS_FILENAME = "/etc/dictionaries-common/words"
def measure(func):
measure.func_to_measure.append(func)
return func
measure.func_to_measure = []
@measure
def dcrosta():
words = [line.strip() for line in open(WORDS_FILENAME)]
return random.choice(words)
@measure
def dcrosta_no_strip():
words = [line for line in open(WORDS_FILENAME)]
return random.choice(words)
def select_random_line(filename):
selection = None
count = 0
for line in file(filename, "r"):
if random.randint(0, count) == 0:
selection = line.strip()
count = count + 1
return selection
@measure
def mark_ransom():
return select_random_line(WORDS_FILENAME)
def select_random_line_no_strip(filename):
selection = None
count = 0
for line in file(filename, "r"):
if random.randint(0, count) == 0:
selection = line
count = count + 1
return selection
@measure
def mark_ransom_no_strip():
return select_random_line_no_strip(WORDS_FILENAME)
def choose_from(iterable):
"""Choose a random element from a finite `iterable`.
If `iterable` is a sequence then use `random.choice()` for efficiency.
Return tuple (random element, total number of elements)
"""
selection, i = None, None
for i, item in enumerate(iterable):
if random.randint(0, i) == 0:
selection = item
return selection, (i+1 if i is not None else 0)
@measure
def mark_ransom_choose_from():
return choose_from(open(WORDS_FILENAME))
@measure
def nadia():
global total_num_lines
total_num_lines = sum(1 for _ in open(WORDS_FILENAME))
line_number = random.randint(0, total_num_lines)
return linecache.getline(WORDS_FILENAME, line_number)
@measure
def nadia_known_num_lines():
line_number = random.randint(0, total_num_lines)
return linecache.getline(WORDS_FILENAME, line_number)
@measure
def jfs():
return random.choice(list(open(WORDS_FILENAME)))
def timef(func, number=1000, timer=default_timer):
"""Return number of seconds it takes to execute `func()`."""
start = timer()
for _ in range(number):
func()
return (timer() - start) / number
def main():
# measure time
times = dict((f.__name__, timef(f, number=10))
for f in measure.func_to_measure)
# print from fastest to slowest
maxname_len = max(map(len, times))
last = None
for name in sorted(times, key=times.__getitem__):
print "%s %4.2g seconds %.2f" % (name.ljust(maxname_len), times[name],
last and times[name] / last or 1)
last = times[name]
if __name__ == "__main__":
main()
# nadia_known_num_lines 9.6e-06 seconds 1.00
# nadia 0.056 seconds 5843.51
# jfs 0.062 seconds 1.10
# dcrosta_no_strip 0.091 seconds 1.48
# dcrosta 0.13 seconds 1.41
# mark_ransom_no_strip 0.66 seconds 5.10
# mark_ransom_choose_from 0.67 seconds 1.02
# mark_ransom 0.69 seconds 1.04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment