Skip to content

Instantly share code, notes, and snippets.

@crap0101
Last active May 2, 2022 07:06
Show Gist options
  • Save crap0101/569183de102a968801794c595b608173 to your computer and use it in GitHub Desktop.
Save crap0101/569183de102a968801794c595b608173 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# Cfr. https://forum.ubuntu-it.org/viewtopic.php?f=33&t=649253
import argparse
import collections
import random
import sys
import timeit
RTIMES = 1000
MIN_CHR = 48 # 0
MAX_CHR = 2000 # 0x10ffff
STR_LEN = 100
WDICT = '/usr/share/dict/italian'
#GC ~= not enabled by default
_gc_enable = 'gc.enable()'
_funcs = tuple('''test_dict_VaeVictis test_dict_VaeVictis2
test_cdict test_counter test_counter2
test_Claudio_F test_Claudio_F_f'''.split())
_test_types = tuple('wdict string anagr'.split())
def _get_parser ():
parser = argparse.ArgumentParser(description='test speed on some anagr functions')
parser.add_argument('-d', '--words-dict-path', dest='wdict', default=WDICT,
help='path to a words file (one by line). Default: %(default)s')
parser.add_argument('-l', '--len', dest='str_len', type=int, default=STR_LEN,
help='max length of the random generated strings. Default: %(default)s')
parser.add_argument('-m', '--min', dest='min_chr', type=int, default=MIN_CHR,
help='min value for random character generation (using chr()). Default: %(default)s')
parser.add_argument('-M', '--max', dest='max_chr', type=int, default=MAX_CHR,
help='max value for random character generation (using chr()). Default: %(default)s')
parser.add_argument('-g', '--garbage', dest='gc_enable', action='store_true',
help='enable garbage collection')
parser.add_argument('-f', '--funcs', dest='funclist', choices=_funcs, nargs='+', default=_funcs,
metavar='funcname', help='funcs to run (default: all). Choices from: %(default)s')
parser.add_argument('-r', '--repeat', dest='repeat', type=int, default=RTIMES,
help='timeit() number executions. Default: %(default)s')
parser.add_argument('-t', '--test-type', dest='test_type', choices=_test_types, nargs='+', default=_test_types,
metavar='test_name', help='kind of test to run (default: all). Choices from: %(default)s')
parser.add_argument('-T', '--run-tests', dest='testing', action='store_true',
help='run some tests and exit (not really :-D to be implemented...)')
return parser
#
# strings generation/retrieval
#
def _random_words (path=WDICT):
words = []
with open(path) as wlist:
for word in wlist:
words.append(word.strip().lower())
return words
def _random_str (length=STR_LEN, bottom=MIN_CHR, top=MAX_CHR):
return ''.join(
chr(random.randrange(bottom, top))
for n in range(length))
#
# Utility functions
#
def make_counter (iterable):
return collections.Counter(iterable)
def make_cdict (iterable):
return dict(make_counter(iterable))
def make_dict (iterable):
d = {}
for element in iterable:
d[element] = d.get(element, 0) + 1
return d
# not used
def make_set (iterable, frozen=False):
return frozenset(iterable) if frozen else set(iterable)
#
# Test functions
#
def test_counter (s1, s2):
return make_counter(s1) == make_counter(s2)
def test_counter2 (s1, s2):
return collections.Counter(s1) == collections.Counter(s2)
def test_cdict (s1, s2):
return make_cdict(s1) == make_cdict(s2)
def test_dict_VaeVictis (s1, s2):
return make_dict(s1) == make_dict(s2)
def test_dict_VaeVictis2 (s1, s2):
d1 = {}
d2 = {}
for element in s1:
d1[element] = d1.get(element, 0) + 1
for element in s2:
d2[element] = d2.get(element, 0) + 1
return d1 == d2
def test_Claudio_F (s1, s2):
return (len(s1) == len(s2) and all(s1.count(x) == s2.count(x)
for x in set(s1)))
def test_Claudio_F_f (s1, s2):
return (len(s1) == len(s2) and all(s1.count(x) == s2.count(x)
for x in frozenset(s1)))
def _get_data(cfg):
_w = _random_words(cfg.wdict)
_pairw = tuple((random.choice(_w), random.choice(_w)) for _ in _w)
_s = tuple(_random_str(cfg.str_len, cfg.min_chr, cfg.max_chr) for _ in range(1000))
_pairstr = tuple((random.choice(_s), random.choice(_s)) for _ in _s)
_palstr = tuple((s1, s1[::-1]) for s1,_ in _pairstr)
return _pairw, _pairstr, _palstr
def _test_eq ():
print("Running some tests..")
g = globals()
flist = tuple(g[f] for f in _funcs)
_strings = [('abc', 'cba'), ('qwerty', 'qwerto')]
for p in _strings:
assert len(set(f(*p) for f in flist)) == 1
print("OK.")
if __name__ == '__main__':
pargs = _get_parser().parse_args()
_words, _strings, _pal = _get_data(pargs)
_setup_partial = 'from __main__ import {} as _f, _strings, _words, _pal'
_respr = '{0:<20} {1:<15} {2:>.4f}s'
if pargs.testing:
_test_eq()
sys.exit(0)
if pargs.gc_enable:
_setup_partial += '; gc.enable()'
for f in pargs.funclist:
_setup = _setup_partial.format(f)
if 'string' in pargs.test_type:
_t = timeit.Timer('for p in _strings: _f(*p)', setup=_setup).timeit(number=pargs.repeat)
print(_respr.format(f, '[_strings]:', _t / pargs.repeat))
if 'wdict' in pargs.test_type:
_t = timeit.Timer('for p in _words: _f(*p)', setup=_setup).timeit(number=pargs.repeat)
print(_respr.format(f, '[_words]:', _t / pargs.repeat))
if 'anagr' in pargs.test_type:
_t = timeit.Timer('for p in _pal: _f(*p)', setup=_setup).timeit(number=pargs.repeat)
print(_respr.format(f, '[_pal]:', _t / pargs.repeat))
"""
crap0101@orange:~/test$ python3 py-dict-set-speed.py -r 100
test_dict_VaeVictis [_strings]: 0.0586s
test_dict_VaeVictis [_words]: 0.5270s
test_dict_VaeVictis [_pal]: 0.0628s
test_dict_VaeVictis2 [_strings]: 0.0586s
test_dict_VaeVictis2 [_words]: 0.5111s
test_dict_VaeVictis2 [_pal]: 0.0621s
test_cdict [_strings]: 0.0504s
test_cdict [_words]: 0.9020s
test_cdict [_pal]: 0.0537s
test_counter [_strings]: 0.0417s
test_counter [_words]: 0.7140s
test_counter [_pal]: 0.0453s
test_counter2 [_strings]: 0.0413s
test_counter2 [_words]: 0.6889s
test_counter2 [_pal]: 0.0449s
test_Claudio_F [_strings]: 0.0140s
test_Claudio_F [_words]: 0.0923s
test_Claudio_F [_pal]: 0.0844s
test_Claudio_F_f [_strings]: 0.0141s
test_Claudio_F_f [_words]: 0.0916s
test_Claudio_F_f [_pal]: 0.0841s
crap0101@orange:~/test$ python3 py-dict-set-speed.py -r 100 -t anagr -f test_dict_VaeVictis2 test_Claudio_F test_Claudio_F_f test_counter2
test_dict_VaeVictis2 [_pal]: 0.0629s
test_Claudio_F [_pal]: 0.0849s
test_Claudio_F_f [_pal]: 0.0850s
test_counter2 [_pal]: 0.0461s
crap0101@orange:~/test$ python3 py-dict-set-speed.py -r 100 -t anagr -f test_dict_VaeVictis2 test_Claudio_F test_Claudio_F_f test_counter2 -g
test_dict_VaeVictis2 [_pal]: 0.0630s
test_Claudio_F [_pal]: 0.0849s
test_Claudio_F_f [_pal]: 0.0850s
test_counter2 [_pal]: 0.0457s
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment