Skip to content

Instantly share code, notes, and snippets.

@vovanbo
Last active March 17, 2017 19:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vovanbo/dbb3044b417bcd407a4411119aacf415 to your computer and use it in GitHub Desktop.
Save vovanbo/dbb3044b417bcd407a4411119aacf415 to your computer and use it in GitHub Desktop.
Improved atoms iterator benchmark
from schematics.undefined import Undefined
from schematics.compat import iteritems
from schematics.iteration import Atom
from schematics.types import IntType, ListType, DictType, ModelType
from schematics import Model
def old_atoms(schema, mapping, keys=Atom._fields, filter=None):
atom_dict = dict.fromkeys(Atom._fields)
keys_set = set(keys)
if not keys_set.issubset(atom_dict):
raise TypeError('invalid key specified')
has_value = (mapping is not None) and ('value' in keys_set)
for field_name, field in iteritems(schema.fields):
atom_dict['name'] = field_name
atom_dict['field'] = field
atom_dict['value'] = Undefined
if has_value:
try:
value = getattr(mapping, field_name)
except AttributeError:
value = mapping.get(field_name, Undefined)
except Exception:
value = Undefined
atom_dict['value'] = value
atom_tuple = Atom(**dict((k, atom_dict.get(k)) for k in keys))
if filter is None:
yield atom_tuple
elif filter(atom_tuple):
yield atom_tuple
def new_atoms(schema, mapping, keys=Atom._fields, filter=None):
if not set(keys).issubset(Atom._fields):
raise TypeError('invalid key specified')
has_value = (mapping is not None) and ('value' in keys)
for field_name, field in iteritems(schema.fields):
value = Undefined
if has_value:
try:
value = getattr(mapping, field_name)
except AttributeError:
value = mapping.get(field_name, Undefined)
except Exception:
value = Undefined
atom_tuple = Atom(name=field_name, field=field, value=value)
if filter is None:
yield atom_tuple
elif filter(atom_tuple):
yield atom_tuple
class M(Model):
intfield = IntType(max_value=2)
matrixfield = ListType(ListType(IntType))
dictfield = DictType(IntType)
modelfield = ModelType('M')
origdict = {
'intfield': '1',
'dictfield': dict(a=1, b=2),
'modelfield': {
'intfield': '2',
'matrixfield': [[0, 0, 0], [1, 1, 1], [2, 2, 2]],
'dictfield': dict(a=11, b=22),
'modelfield': {
'intfield': '3',
'dictfield': dict(a=111, b=222)}}}
if __name__ == '__main__':
import timeit
print('New atoms',
timeit.timeit("[(field_name, field, value) for field_name, field, value in new_atoms(M._schema, origdict)]",
globals=globals(), number=100000)
)
print('Old atoms',
timeit.timeit("[(field_name, field, value) for field_name, field, value in old_atoms(M._schema, origdict)]",
globals=globals(), number=100000)
)
@vovanbo
Copy link
Author

vovanbo commented Mar 17, 2017

Results:

New atoms 1.9814772070003528
Old atoms 3.257906824001111

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment