为棉花糖加速转储和加载对象的jit实现。
toastedmarshmallow的Python项目详细描述
烤棉花糖对棉花糖实施jit,加速倾倒 对象10-25x(取决于架构)。烤棉花糖让你 有很好的api Marshmallow提供 不用牺牲表演!
Benchmark Result: Original Time: 2682.61 usec/dump Optimized Time: 176.38 usec/dump Speed up: 15.21x
即使是PyPy也能从toastedmarshmallow中获益!
Benchmark Result: Original Time: 189.78 usec/dump Optimized Time: 20.03 usec/dump Speed up: 9.48x
安装toastedmarshmlow
pip install toastedmarshmallow
这也将安装一个稍微分叉的marshmallow,其中包括 hooks toastedmarshmlow needs允许jit在返回之前运行 原来的棉花糖密码。这些变化很小,使之更容易 追踪上游。你可以找到变化 Here。
这意味着您应该从您的需求中删除marshmallow,并且 替换为toastedmarshmallow。默认情况下没有 区别,除非您显式启用烤棉花糖。
启用烤棉花糖
在现有模式上启用烤棉花糖只是一行代码, 将任何Schema实例上的jit属性设置为 toastedmarshmallow.Jit。例如:
fromdatetimeimportdateimporttoastedmarshmallowfrommarshmallowimportSchema,fields,pprintclassArtistSchema(Schema):name=fields.Str()classAlbumSchema(Schema):title=fields.Str()release_date=fields.Date()artist=fields.Nested(ArtistSchema())schema=AlbumSchema()# Specify the jit method as toastedmarshmallow's jitschema.jit=toastedmarshmallow.Jit# And that's it! Your dump methods are 15x faster!
也可以在Marshmallow模式上使用Meta类 要指定给定Schema的所有实例,应进行优化:
importtoastedmarshmallowfrommarshmallowimportSchema,fields,pprintclassArtistSchema(Schema):classMeta:jit=toastedMarshmallow.Jitname=fields.Str()
您还可以通过设置环境全局启用烤棉花糖 变量MARSHMALLOW_SCHEMA_DEFAULT_JIT到toastedmarshmallow.Jit。 烤棉花糖的未来版本可能会将其设为默认值。
工作原理
烤棉花糖的工作原理是在运行时生成代码以优化转储 没有经过层层反射的物体。生成的 代码乐观地假设传入的对象是示意性有效的, 在失败时回到原来的棉花糖代码。
例如,从上面取AlbumSchema,toastedmarshmlow将 生成以下3种方法:
defInstanceSerializer(obj):res={}value=obj.release_date;value=value()ifcallable(value)elsevalue;res["release_date"]=_field_release_date__serialize(value,"release_date",obj)value=obj.artist;value=value()ifcallable(value)elsevalue;res["artist"]=_field_artist__serialize(value,"artist",obj)value=obj.title;value=value()ifcallable(value)elsevalue;value=str(value)ifvalueisnotNoneelseNone;res["title"]=valuereturnresdefDictSerializer(obj):res={}if"release_date"inobj:value=obj["release_date"];value=value()ifcallable(value)elsevalue;res["release_date"]=_field_release_date__serialize(value,"release_date",obj)if"artist"inobj:value=obj["artist"];value=value()ifcallable(value)elsevalue;res["artist"]=_field_artist__serialize(value,"artist",obj)if"title"inobj:value=obj["title"];value=value()ifcallable(value)elsevalue;value=str(value)ifvalueisnotNoneelseNone;res["title"]=valuereturnresdefHybridSerializer(obj):res={}try:value=obj["release_date"]except(KeyError,AttributeError,IndexError,TypeError):value=obj.release_datevalue=value;value=value()ifcallable(value)elsevalue;res["release_date"]=_field_release_date__serialize(value,"release_date",obj)try:value=obj["artist"]except(KeyError,AttributeError,IndexError,TypeError):value=obj.artistvalue=value;value=value()ifcallable(value)elsevalue;res["artist"]=_field_artist__serialize(value,"artist",obj)try:value=obj["title"]except(KeyError,AttributeError,IndexError,TypeError):value=obj.titlevalue=value;value=value()ifcallable(value)elsevalue;value=str(value)ifvalueisnotNoneelseNone;res["title"]=valuereturnres
toastedmarshmlow将根据输入调用适当的序列化程序。
由于toastedmarshmlow在运行时生成代码,因此 重用架构对象。如果每次创建新的schema对象时 序列化/反序列化对象的性能可能会差得多。