boltons/misc/bench_omd.py

124 lines
3.3 KiB
Python

# -*- coding: utf-8 -*-
from __future__ import print_function
import string
import sys
sys.path.append('/home/mahmoud/projects/lithoxyl/')
import time
import lithoxyl
from lithoxyl import sinks, logger
from dictutils import OMD, FastIterOrderedMultiDict
from collections import OrderedDict as OD
q_sink = lithoxyl.sinks.QuantileSink()
log = lithoxyl.logger.BaseLogger('bench_stats', sinks=[q_sink])
try:
profile
except NameError:
times = 10
size = 10000
redun = 2
else:
times = 1
size = 10000
redun = 10
_rng = range(size / redun) * redun
_unique_keys = set(_rng)
_bad_rng = range(size, size + size)
_pairs = zip(_rng, _rng)
# order matters because 'pop' mutates
_shared_actions = ('setitem', 'iteritems', 'iterkeys', 'getitem', 'keyerror', 'pop')
_multi_actions = ('multi_iteritems',)
_all_actions = ('init',) + _multi_actions + _shared_actions
MULTI_IMPLS = (FastIterOrderedMultiDict, OMD)
try:
from werkzeug.datastructures import MultiDict, OrderedMultiDict as WOMD
MULTI_IMPLS += (WOMD, MultiDict)
except ImportError:
print('(installing werkzeug is recommended for full comparison)')
ALL_IMPLS = MULTI_IMPLS + (OD, dict)
def bench():
for impl in ALL_IMPLS:
q_sink = lithoxyl.sinks.QuantileSink()
impl_name = '.'.join([impl.__module__, impl.__name__])
log = lithoxyl.logger.BaseLogger(impl_name, sinks=[q_sink])
print()
print('+ %s' % impl_name)
for _ in range(times):
with log.info('total'):
for _ in range(times):
with log.info('init'):
target_dict = impl(_pairs)
if impl in MULTI_IMPLS:
_actions = _multi_actions + _shared_actions
else:
_actions = _shared_actions
for action in _actions:
action_func = globals()['_do_' + action]
with log.info(action):
action_func(target_dict)
for action in _all_actions:
try:
best_msecs = q_sink.qas[impl_name][action].min * 1000
print(' - %s - %g ms' % (action, best_msecs))
except KeyError:
pass
best_msecs = q_sink.qas[impl_name]['total'].min * 1000
median_msecs = q_sink.qas[impl_name]['total'].median * 1000
print(' > ran %d loops of %d items each, best time: %g ms, median time: %g ms' % (times, size, best_msecs, median_msecs))
print()
return
def _do_setitem(target_dict):
for k, i in enumerate(string.lowercase):
target_dict[k] = i
def _do_iteritems(target_dict):
[_ for _ in target_dict.iteritems()]
def _do_iterkeys(target_dict):
[_ for _ in target_dict.iterkeys()]
def _do_multi_iteritems(target_dict):
[_ for _ in target_dict.iteritems(multi=True)]
def _do_multi_iterkeys(target_dict):
[_ for _ in target_dict.iterkeys(multi=True)]
def _do_getitem(target_dict):
for k in _rng:
target_dict[k]
def _do_keyerror(target_dict):
for k in _bad_rng:
try:
target_dict[k]
except KeyError:
pass
def _do_pop(target_dict):
for k in _unique_keys:
target_dict.pop(k)
assert not target_dict
if __name__ == '__main__':
bench()