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]) times = 10 size = 10000 redun = 2 _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(f' - {action} - {best_msecs:g} ms') 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()