Created
July 29, 2021 08:28
-
-
Save Compro-Prasad/fd6fc8169dd46a611ba7dba4943d63c2 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import random | |
from collections import defaultdict | |
from pprint import pprint | |
from timeit import timeit | |
def get_configs(n=1000): | |
a2z = "abcdefghijklmnopqrstuvwxyz" | |
configs = defaultdict(set) | |
conds = set() | |
for _ in range(n): | |
name = "".join(random.sample(a2z, k=4)) | |
config = configs[name] | |
fields = set(random.sample(a2z, k=random.randint(1, 5))) | |
related_conds = {cond[0] for cond in conds if cond in fields or cond[0] in fields} | |
while len(config) != len(fields): | |
remaining_fields = tuple( | |
fields - | |
{c[0] if isinstance(c, tuple) else c for c in config} | |
) | |
if not remaining_fields: | |
break | |
field = random.choice(remaining_fields) | |
value = random.choice((None, random.randint(1, 5))) | |
cond = field if value is None else (field, value) | |
cond = random.choice(tuple({cond}.union(related_conds))) | |
conds.add(cond) | |
config.add(cond) | |
return configs | |
# x = { | |
# 'System cpu': ['x', {'y': 2}], | |
# 'System mem': ['x', {'y': 2}, {'z': 1}], | |
# 'Main cpu': [{'y': 2}], | |
# 'Main memry': [{'x': 3}] | |
# } | |
# x = { | |
# 'jgkx': {('a', 1)}, | |
# 'qhmt': {('a', 1), 'x', ('p', 1), 'k', 'm'}, | |
# 'uyvq': {'k'} | |
# } | |
# x = get_configs(3) | |
# pprint(x) | |
def compile_matchers(configs, sort=True): | |
z = defaultdict(set) | |
for name, conds in configs.items(): | |
for cond in conds: | |
z[cond].add(name) | |
if not sort: | |
return tuple(z.items()) | |
return tuple( | |
sorted(tuple(z.items()), key=lambda x: len(x[1]), reverse=True) | |
) | |
def get_fields(configs, sort=True): | |
z = defaultdict(set) | |
for name, conds in configs.items(): | |
for cond in conds: | |
z[cond[0]].add(name) | |
if not sort: | |
return tuple(z.items()) | |
return tuple( | |
sorted(tuple(z.items()), key=lambda x: len(x[1]), reverse=True) | |
) | |
def set_check(y, matchers): | |
matched = set() | |
not_matched = set() | |
for cond, names in matchers: | |
if isinstance(cond, str): | |
matched.update(names) if cond in y \ | |
else not_matched.update(names) | |
elif isinstance(cond, tuple): | |
matched.update(names) if y.get(cond[0]) == cond[1] \ | |
else not_matched.update(names) | |
return matched - not_matched | |
def fields_check(y, fields): | |
matched = set() | |
not_matched = set() | |
for cond, names in fields: | |
matched.update(names) if cond in y \ | |
else not_matched.update(names) | |
return matched - not_matched | |
def com_check(y, all_configs, all_configs_fields): | |
matchers = compile_matchers( | |
{ | |
name: all_configs[name] | |
for name in fields_check(y, all_configs_fields) | |
}, | |
sort=False | |
) | |
return set_check(y, matchers) | |
def old_check(y, configs): | |
final = set() | |
for name, conds in configs.items(): | |
f = True | |
for cond in conds: | |
if isinstance(cond, str): | |
if cond not in y: | |
f = False | |
break | |
elif isinstance(cond, tuple): | |
if y.get(cond[0]) != cond[1]: | |
f = False | |
break | |
if f: | |
final.add(name) | |
return final | |
ALL_CONFIGS = get_configs(400) | |
ALL_CONFIGS_COMPILED = compile_matchers(ALL_CONFIGS) | |
ALL_CONFIGS_FIELDS = get_fields(ALL_CONFIGS) | |
TIMES = 10000 | |
print("SET:", timeit(''' | |
set_check( | |
{ | |
'a': 1, | |
'k': 3 | |
}, | |
ALL_CONFIGS_COMPILED | |
) | |
''', | |
setup='from __main__ import set_check, ALL_CONFIGS_COMPILED', | |
number=TIMES)) | |
print("COM:", timeit(''' | |
com_check( | |
{ | |
'a': 1, | |
'k': 3 | |
}, | |
ALL_CONFIGS, | |
ALL_CONFIGS_FIELDS | |
) | |
''', | |
setup='from __main__ import com_check, ALL_CONFIGS, ALL_CONFIGS_FIELDS', | |
number=TIMES)) | |
print("OLD:", timeit(''' | |
old_check( | |
{ | |
'a': 1, | |
'k': 3 | |
}, | |
ALL_CONFIGS | |
) | |
''', | |
setup='from __main__ import old_check, ALL_CONFIGS', | |
number=TIMES)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment