Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Comparison between Marshmallow and Colander
import timeit
import uuid
import colander
import marshmallow
class BarList(colander.SequenceSchema):
item = colander.SchemaNode(
colander.Integer(), validator=colander.Range(min=1))
class SignupSchema(colander.MappingSchema):
def schema_type():
return colander.Mapping(unknown='preserve')
username = colander.SchemaNode(colander.String())
foo = colander.SchemaNode(
colander.Integer(), validator=colander.Range(min=1))
bar = BarList()
def def_uuid(node, kw):
return str(uuid.uuid4())
def def_validator(node, kw):
return colander.Function(lambda v: kw['bound'] == v)
class SignupSchemaWithDeferred(SignupSchema):
uuid = colander.SchemaNode(colander.String(), missing=def_uuid)
bound = colander.SchemaNode(colander.String(), validator=def_validator)
class SignupSchemaM(marshmallow.Schema):
class Meta:
strict = True
ordered = True
preserve = True
username = marshmallow.fields.String(required=True)
foo = marshmallow.fields.Integer(
bar = marshmallow.fields.List(marshmallow.fields.Integer(
validate=[marshmallow.validate.Range(min=1)]), many=True)
def _add_unknown(self, data, original):
"""Preserve unknown keys during deserialization."""
for key, val in original.items():
if key not in self.fields:
data[key] = val
return data
class SignupSchemaContextM(SignupSchemaM):
uuid = marshmallow.fields.String(missing=lambda: str(uuid.uuid4()))
bound = marshmallow.fields.String()
def validate_bound(self, value):
if self.context['bound'] != value:
raise marshmallow.ValidationError('WRONG!')
data = {'foo': 1, 'bar': [1, 2, 3],
'bound': 'YYYY',
'baz': {'a': 'test',
'b': ['a', 'b', 'c']},
'username': 'ergo'}
colander_schema = SignupSchema()
def test_colander():
return colander_schema.deserialize(data)
colander_bind_schema = SignupSchemaWithDeferred()
def test_colander_bind():
schema = colander_bind_schema.bind(bound='YYYY')
return schema.deserialize(data)
ma_schema = SignupSchemaM()
def test_marshmallow():
return ma_schema.load(data)
ma_context_schema = SignupSchemaContextM()
ma_context_schema.context.setdefault('bound', 'YYYY')
def test_marshmallow_context():
return ma_context_schema.load(data)
c_result = timeit.timeit(test_colander, number=10000)
m_result = timeit.timeit(test_marshmallow, number=10000)
print(f'Colander took {c_result:.4f}')
print(f'Marshmallow took {m_result:.4f}')
print(f'Marshmallow took {m_result/c_result:.2f}x of Colander execution time')
print('\nNow testing with binds/context\n')
c_result = timeit.timeit(test_colander_bind, number=10000)
m_result = timeit.timeit(test_marshmallow_context, number=10000)
print(f'Colander w/bind took {c_result:.4f}')
print(f'Marshmallow w/context took {m_result:.4f}')
print(f'Marshmallow w/context took {m_result/c_result:.2f}x of Colander w/bind execution time')

This comment has been minimized.

Copy link
Owner Author

sloria commented Apr 12, 2018

Marshmallow 2

Colander took 0.1307
Marshmallow took 0.3534
Marshmallow took 2.70x of Colander execution time

Now testing with binds/context

Colander w/bind took 3.8629
Marshmallow w/context took 0.5908
Marshmallow w/context took 0.15x of Colander w/bind execution time

Marshmallow 3

Colander took 0.1407
Marshmallow took 0.3630
Marshmallow took 2.58x of Colander execution time

Now testing with binds/context

Colander w/bind took 3.6548
Marshmallow w/context took 0.5586
Marshmallow w/context took 0.15x of Colander w/bind execution time
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.