Skip to content

Instantly share code, notes, and snippets.

@Compro-Prasad
Created July 29, 2021 08:28
Show Gist options
  • Save Compro-Prasad/fd6fc8169dd46a611ba7dba4943d63c2 to your computer and use it in GitHub Desktop.
Save Compro-Prasad/fd6fc8169dd46a611ba7dba4943d63c2 to your computer and use it in GitHub Desktop.
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