Last active
May 2, 2022 07:06
-
-
Save crap0101/569183de102a968801794c595b608173 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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