Skip to main content

Marshmallow 的 JIT 实现,用于加速转储和加载对象。

项目描述

Toasted Marshmallow 为 marshmallow 实现了一个 JIT,它可以将转储对象的速度提高 10-25 倍(取决于您的架构)。Toasted Marshmallow 允许您拥有 Marshmallow提供的出色 API,而无需牺牲性能!

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

安装烤棉花糖

pip install toastedmarshmallow

这还将安装一个稍微分叉的棉花糖,其中包括一些 Toastedmarshmallow 需要的钩子,使 JIT 能够在回退到原始棉花糖代码之前运行。这些变化很小,因此更容易跟踪上游。您可以在此处找到更改 。

这意味着您应该从需求中删除 marshmallow并将其替换为toastedmarshmallow。默认情况下没有区别,除非您明确启用 Toasted Marshmallow。

启用烤棉花糖

在现有 Schema 上启用 Toasted Marshmallow 只是一行代码,将任何Schema实例 上的jit属性设置为toastedmarshmallow.Jit。例如:

from datetime import date
import toastedmarshmallow
from marshmallow import Schema, fields, pprint

class ArtistSchema(Schema):
    name = fields.Str()

class AlbumSchema(Schema):
    title = fields.Str()
    release_date = fields.Date()
    artist = fields.Nested(ArtistSchema())

schema = AlbumSchema()
# Specify the jit method as toastedmarshmallow's jit
schema.jit = toastedmarshmallow.Jit
# And that's it!  Your dump methods are 15x faster!

也可以在Marshmallow模式上使用Meta类来指定应该优化给定模式的所有实例:

import toastedmarshmallow
from marshmallow import Schema, fields, pprint

class ArtistSchema(Schema):
    class Meta:
        jit = toastedMarshmallow.Jit
    name = fields.Str()

您还可以通过将环境变量 MARSHMALLOW_SCHEMA_DEFAULT_JIT 设置为 toastedmarshmallow.Jit 来全局启用Toasted Marshmallow。Toasted Marshmallow 的未来版本可能会将其设为默认值。

这个怎么运作

Toasted Marshmallow 通过在运行时生成代码来优化转储对象,而无需经过层层反射。生成的代码乐观地假设传入的对象在示意上是有效的,失败时回退到原始的棉花糖代码。

例如,从上面获取AlbumSchema,Toastedmarshmallow 将生成以下 3 个方法:

def InstanceSerializer(obj):
    res = {}
    value = obj.release_date; value = value() if callable(value) else value; res["release_date"] = _field_release_date__serialize(value, "release_date", obj)
    value = obj.artist; value = value() if callable(value) else value; res["artist"] = _field_artist__serialize(value, "artist", obj)
    value = obj.title; value = value() if callable(value) else value; value = str(value) if value is not None else None; res["title"] = value
    return res

def DictSerializer(obj):
    res = {}
    if "release_date" in obj:
        value = obj["release_date"]; value = value() if callable(value) else value; res["release_date"] = _field_release_date__serialize(value, "release_date", obj)
    if "artist" in obj:
        value = obj["artist"]; value = value() if callable(value) else value; res["artist"] = _field_artist__serialize(value, "artist", obj)
    if "title" in obj:
        value = obj["title"]; value = value() if callable(value) else value; value = str(value) if value is not None else None; res["title"] = value
    return res

def HybridSerializer(obj):
    res = {}
    try:
        value = obj["release_date"]
    except (KeyError, AttributeError, IndexError, TypeError):
        value = obj.release_date
    value = value; value = value() if callable(value) else value; res["release_date"] = _field_release_date__serialize(value, "release_date", obj)
    try:
        value = obj["artist"]
    except (KeyError, AttributeError, IndexError, TypeError):
        value = obj.artist
    value = value; value = value() if callable(value) else value; res["artist"] = _field_artist__serialize(value, "artist", obj)
    try:
        value = obj["title"]
    except (KeyError, AttributeError, IndexError, TypeError):
        value = obj.title
    value = value; value = value() if callable(value) else value; value = str(value) if value is not None else None; res["title"] = value
    return res

Toastedmarshmallow 将根据输入调用适当的序列化程序。

由于 Toastedmarshmallow 在运行时生成代码,因此重用 Schema 对象至关重要。如果每次序列化/反序列化对象时都创建一个新的 Schema 对象,则性能可能会差得多。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

toastedmarshmallow-2.15.2.post1.tar.gz (62.3 kB 查看哈希

已上传 source