marshmallowのdumpをupdate_fieldsを指定せずに使うと型の調査が入るので遅い。
http://marshmallow.readthedocs.org/en/latest/api_reference.html#marshmallow.Schema.dump
update_fieldsという引数がdefaultでTrueになっていて。これは値のtypeを見て、変換する関数を変えている。具体的なmappingはmarshmallow.schemaにかかれていて以下の様な感じ。
TYPE_MAPPING = { text_type: fields.String, binary_type: fields.String, dt.datetime: fields.DateTime, float: fields.Float, bool: fields.Boolean, tuple: fields.Raw, list: fields.Raw, set: fields.Raw, int: fields.Integer, uuid.UUID: fields.UUID, dt.time: fields.Time, dt.date: fields.Date, dt.timedelta: fields.TimeDelta, decimal.Decimal: fields.Decimal, }
このため例えば以下のようなコードが動作する。
from marshmallow import Schema, fields from datetime import datetime class PersonSchema0(Schema): class Meta: fields = ("name", "age", "ctime") class Person(object): def __init__(self, name, age, ctime): self.name = name self.age = age self.ctime = ctime schema = PersonSchema0() print(schema.dump(Person("foo", 20, datetime.now()))) # MarshalResult(data={'ctime': '2015-03-26T21:34:06.308849+00:00', 'name': 'foo', 'age': 20}, errors={})
PersonSchemaではfieldの型を直接指定していないが、渡された値の型を調べて対応した出力関数でdumpしてくれている。
update_fields=Trueのオーバーヘッド
もちろん先の値の型をチェックしての出力関数の決定にはオーバーヘッドが存在していて。同じ形式の既定の型を出力したい場合にはFalseにすることが速度を気にしたい場合には有効。
from marshmallow import Schema, fields import time from datetime import datetime class PersonSchema0(Schema): class Meta: fields = ("name", "age", "ctime") class Person(object): def __init__(self, name, age, ctime): self.name = name self.age = age self.ctime = ctime N = 1000 schema = PersonSchema0() t = time.time() person = Person("foo", 20, datetime.now()) for i in range(N): schema.dump(person) print(time.time() - t) schema = PersonSchema0() t = time.time() person = Person("foo", 20, datetime.now()) for i in range(N): schema.dump(person, update_fields=False) print(time.time() - t) # 0.15188217163085938 # 0.045701026916503906