Skip to content

Instantly share code, notes, and snippets.

@pablito56
Created February 20, 2014 18:43
Show Gist options
  • Save pablito56/9120441 to your computer and use it in GitHub Desktop.
Save pablito56/9120441 to your computer and use it in GitHub Desktop.
Benchmarking the use of memoize for regular expression transformations and generators. Based on https://gist.github.com/drslump/9109647
#!/usr/bin/env python
def memoize(fn):
""" Memoization decorator for a function taking one or more arguments.
NOTE: Only hashable values can be given as arguments to the function.
http://code.activestate.com/recipes/578231-probably-the-fastest-memoization-decorator-in-the-/#c4
"""
class memodict(dict):
def __getitem__(self, *args):
return dict.__getitem__(self, args)
def __missing__(self, args):
ret = self[args] = fn(*args)
return ret
return memodict().__getitem__
import re
UNDER_TO_CAMEL = re.compile(r'(^|_)(.)')
def underscore_to_camel_case(name):
return UNDER_TO_CAMEL.sub(lambda x: x.group(2).upper(), name)
@memoize
def underscore_to_camel_case_memoized(name):
return underscore_to_camel_case(name)
from itertools import imap
def underscore_to_camel_case_gen(name):
return "".join(imap(lambda word: word.capitalize(), name.split("_")))
def underscore_to_camel_case_gen_bis(name):
return "".join(word.capitalize() for word in name.split("_"))
def convert_case(obj, converter):
if isinstance(obj, dict):
return dict(
(converter(k), convert_case(v, converter))
for k, v in obj.iteritems()
)
elif isinstance(obj, list):
return map(lambda x: convert_case(x, converter), obj)
else:
return obj
ITERATIONS = 1000
import urllib2
import json
print("Fetching GitHub's public timeline...")
req = urllib2.Request('https://github.com/timeline', None, dict(accept='application/json'))
resp = urllib2.urlopen(req)
content = json.loads(resp.read())
import timeit
print("Benchmarking for {0} iterations".format(ITERATIONS))
r1 = timeit.timeit(lambda: convert_case(content, underscore_to_camel_case), number=ITERATIONS)
r2 = timeit.timeit(lambda: convert_case(content, underscore_to_camel_case_memoized), number=ITERATIONS)
r3 = timeit.timeit(lambda: convert_case(content, underscore_to_camel_case_gen), number=ITERATIONS)
r4 = timeit.timeit(lambda: convert_case(content, underscore_to_camel_case_gen_bis), number=ITERATIONS)
print 'Normal/Memoized : {0}s / {1}s -- {2}%'.format(r1, r2, int(r1 * 100 / r2))
print 'Normal/Generator : {0}s / {1}s -- {2}%'.format(r1, r3, int(r1 * 100 / r3))
print 'Normal/Generator 2 : {0}s / {1}s -- {2}%'.format(r1, r4, int(r1 * 100 / r4))
$ python memoize_benchmark_gens.py
Fetching GitHub's public timeline...
Benchmarking for 500 iterations
Normal/Memoized : 3.33840179443s / 1.42423510551s -- 234%
Normal/Generator : 3.33840179443s / 3.4091398716s -- 97%
Normal/Generator 2 : 3.33840179443s / 3.29355096817s -- 101%
$ python memoize_benchmark.py
Fetching GitHub's public timeline...
Benchmarking for 1000 iterations
Normal/Memoized : 6.02346777916s / 2.16515493393s -- 278%
Normal/Generator : 6.02346777916s / 5.86570096016s -- 102%
Normal/Generator 2 : 6.02346777916s / 5.62004804611s -- 107%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment