跳转到主要内容

快速、正确的Python msgpack库,支持dataclasses、datetimes和numpy

项目描述

ormsgpack

PyPI PyPI - Downloads

ormsgpack是Python的一个快速msgpack库。它是orjson的分支/重启。它的序列化速度比msgpack-python快,而反序列化速度略慢(目前)。它支持序列化:dataclassdatetimenumpypydanticUUID实例。

与其他Python msgpack库相比,其功能和缺点

  • 原生序列化dataclass实例。
  • datetimedatetime 实例序列化为 RFC 3339 格式,例如 "1970-01-01T00:00:00+00:00"。
  • 以原生方式并更快地序列化 numpy.ndarray 实例。
  • 以原生方式序列化 pydantic.BaseModel 实例。
  • 使用 default 钩子序列化任意类型。

ormsgpack 支持 CPython 3.8、3.9、3.10、3.11 和 3.12。ormsgpack 不支持 PyPy。版本遵循语义版本规范,默认情况下不启用标记的新对象类型被视为破坏性变更。

ormsgpack 采用 Apache 2.0 和 MIT 许可证。仓库和问题跟踪器是 github.com/aviramha/ormsgpack,补丁可以提交到那里。仓库中提供了一个 CHANGELOG

  1. 使用方法
    1. 安装
    2. 快速入门
    3. 序列化
      1. 默认
      2. 选项
    4. 反序列化
  2. 类型
    1. dataclass
    2. datetime
    3. enum
    4. float
    5. int
    6. numpy
    7. uuid
    8. pydantic
  3. 延迟
  4. 问题
  5. 打包
  6. 许可证

使用方法

安装

要从 PyPI 安装 wheel,请参阅

pip install --upgrade "pip>=20.3" # manylinux_x_y, universal2 wheel support
pip install --upgrade ormsgpack

要构建 wheel,请参阅 打包

快速入门

这是指定选项并序列化、反序列化的示例

>>> import ormsgpack, datetime, numpy
>>> data = {
...     "type": "job",
...     "created_at": datetime.datetime(1970, 1, 1),
...     "status": "🆗",
...     "payload": numpy.array([[1, 2], [3, 4]]),
... }
>>> ormsgpack.packb(data, option=ormsgpack.OPT_NAIVE_UTC | ormsgpack.OPT_SERIALIZE_NUMPY)
b'\x84\xa4type\xa3job\xaacreated_at\xb91970-01-01T00:00:00+00:00\xa6status\xa4\xf0\x9f\x86\x97\xa7payload\x92\x92\x01\x02\x92\x03\x04'
>>> ormsgpack.unpackb(_)
{'type': 'job', 'created_at': '1970-01-01T00:00:00+00:00', 'status': '🆗', 'payload': [[1, 2], [3, 4]]}

序列化

def packb(
    __obj: Any,
    default: Optional[Callable[[Any], Any]] = ...,
    option: Optional[int] = ...,
) -> bytes: ...

packb() 将 Python 对象序列化为 msgpack。

它以原生方式序列化 bytesstrdictlisttupleintfloatbooldataclasses.dataclasstyping.TypedDictdatetime.datetimedatetime.datedatetime.timeuuid.UUIDnumpy.ndarrayNone 实例。它通过 default 支持任意类型。它序列化 strintdictlistdataclasses.dataclassenum.Enum 的子类。为了避免序列化子类,指定选项 ormsgpack.OPT_PASSTHROUGH_SUBCLASS

输出是一个包含 UTF-8 的 bytes 对象。

在调用期间保持全局解释器锁 (GIL)。

对于不支持的类型,它引发 MsgpackEncodeError。此异常消息使用错误消息 "类型不是 msgpack 可序列化: ..." 描述无效对象。要修复此问题,指定 default

如果 str 包含无效的 UTF-8,则引发 MsgpackEncodeError

如果 dict 的键类型不是 strbytes,则引发 MsgpackEncodeError,除非指定了 OPT_NON_STR_KEYS

如果 default 的输出递归到 default 处理超过 254 层,则引发 MsgpackEncodeError

如果存在循环引用,则引发 MsgpackEncodeError

如果 datetime 对象上的 tzinfo 不受支持,则引发 MsgpackEncodeError

MsgpackEncodeErrorTypeError 的子类。

默认

要序列化子类或任意类型,指定 default 为返回支持类型的可调用对象。default 可以是函数、lambda 或可调用类实例。要指定类型未由 default 处理,引发异常,例如 TypeError

>>> import ormsgpack, decimal
>>> def default(obj):
...     if isinstance(obj, decimal.Decimal):
...         return str(obj)
...     raise TypeError
...
>>> ormsgpack.packb(decimal.Decimal("0.0842389659712649442845"))
TypeError: Type is not msgpack serializable: decimal.Decimal
>>> ormsgpack.packb(decimal.Decimal("0.0842389659712649442845"), default=default)
b'\xb80.0842389659712649442845'
>>> ormsgpack.packb({1, 2}, default=default)
TypeError: Type is not msgpack serializable: set

default 可调用对象可以返回一个必须由 default 处理的对象,最多 254 次,然后引发异常。

如果无法处理类型,default 必须引发异常。否则,Python 会隐式返回 None,对于调用者来说看起来像是一个合法值,并被序列化。

>>> import ormsgpack, decimal
>>> def default(obj):
...     if isinstance(obj, decimal.Decimal):
...         return str(obj)
...
>>> ormsgpack.packb({"set":{1, 2}}, default=default)
b'\x81\xa3set\xc0'
>>> ormsgpack.unpackb(_)
{'set': None}

要将类型序列化为 MessagePack 扩展类型,返回一个 ormsgpack.Ext 对象。实例化参数是一个范围在 [0, 127] 内的整数和一个 bytes 对象,分别定义类型和值。

>>> import ormsgpack, decimal
>>> def default(obj):
...     if isinstance(obj, decimal.Decimal):
...         return ormsgpack.Ext(0, str(obj).encode())
...     raise TypeError
...
>>> ormsgpack.packb(decimal.Decimal("0.0842389659712649442845"), default=default)
b'\xc7\x18\x000.0842389659712649442845'

选项

要修改数据序列化的方式,指定 option。每个 optionormsgpack 中的整数常量。要指定多个选项,将它们组合在一起,例如 option=ormsgpack.OPT_NON_STR_KEYS | ormsgpack.OPT_NAIVE_UTC

OPT_NAIVE_UTC

将没有 tzinfodatetime.datetime 对象和 numpy.datetime64 对象序列化为 UTC。这对设置了 tzinfodatetime.datetime 对象没有影响。

>>> import ormsgpack, datetime
>>> ormsgpack.packb(
...     datetime.datetime(1970, 1, 1, 0, 0, 0),
... )
b'\xb31970-01-01T00:00:00'
>>> ormsgpack.unpackb(_)
'1970-01-01T00:00:00'
>>> ormsgpack.packb(
...     datetime.datetime(1970, 1, 1, 0, 0, 0),
...     option=ormsgpack.OPT_NAIVE_UTC,
... )
b'\xb91970-01-01T00:00:00+00:00'
>>> ormsgpack.unpackb(_)
'1970-01-01T00:00:00+00:00'
OPT_NON_STR_KEYS

序列化类型不是 strdict 键。这允许 dict 键为以下类型之一:strintfloatboolNonedatetime.datetimedatetime.datedatetime.timeenum.Enumuuid.UUID

>>> import ormsgpack, datetime, uuid
>>> ormsgpack.packb(
...     {uuid.UUID("7202d115-7ff3-4c81-a7c1-2a1f067b1ece"): [1, 2, 3]},
...     option=ormsgpack.OPT_NON_STR_KEYS,
... )
b'\x81\xd9$7202d115-7ff3-4c81-a7c1-2a1f067b1ece\x93\x01\x02\x03'
>>> ormsgpack.unpackb(_)
{'7202d115-7ff3-4c81-a7c1-2a1f067b1ece': [1, 2, 3]}
>>> ormsgpack.packb(
...     {datetime.datetime(1970, 1, 1, 0, 0, 0): [1, 2, 3]},
...     option=ormsgpack.OPT_NON_STR_KEYS | ormsgpack.OPT_NAIVE_UTC,
... )
b'\x81\xb91970-01-01T00:00:00+00:00\x93\x01\x02\x03'
>>> ormsgpack.unpackb(_)
{'1970-01-01T00:00:00+00:00': [1, 2, 3]}

这些类型通常按照作为值时的方式序列化,例如,datetime.datetime 仍然是 RFC 3339 字符串,并尊重影响它的选项。

此选项存在创建重复键的风险。这是因为非 str 对象可能序列化成与现有键相同的 str,例如,{ "1970-01-01T00:00:00+00:00": true, datetime.datetime(1970, 1, 1, 0, 0, 0): false }。最后插入到 dict 中的键将被最后序列化,并且 msgpack 反序列化器可能假定最后出现的一个键(在上例中为 false)。第一个值将会丢失。

此选项与 ormsgpack.OPT_SORT_KEYS 不兼容。

OPT_OMIT_MICROSECONDS

不序列化 datetime.datetimedatetime.timenumpy.datetime64 实例的微秒部分。

>>> import ormsgpack, datetime
>>> ormsgpack.packb(
...     datetime.datetime(1970, 1, 1, 0, 0, 0, 1),
... )
b'\xba1970-01-01T00:00:00.000001'
>>> ormsgpack.unpackb(_)
'1970-01-01T00:00:00.000001'
>>> ormsgpack.packb(
...     datetime.datetime(1970, 1, 1, 0, 0, 0, 1),
...     option=ormsgpack.OPT_OMIT_MICROSECONDS,
... )
b'\xb31970-01-01T00:00:00'
>>> ormsgpack.unpackb(_)
'1970-01-01T00:00:00'
OPT_PASSTHROUGH_BIG_INT

启用大(Python)整数的透传。通过设置此选项,可以为大于 63 位的整数设置一个 default 函数,较小的整数仍然可以高效地序列化。

>>> import ormsgpack
>>> ormsgpack.packb(
...     2**65,
... )
TypeError: Integer exceeds 64-bit range
>>> ormsgpack.packb(
...     2**65,
...     option=ormsgpack.OPT_PASSTHROUGH_BIG_INT,
...     default=lambda _: {"type": "bigint", "value": str(_) }
... )
b'\x82\xa4type\xa6bigint\xa5value\xb436893488147419103232'
>>> ormsgpack.unpackb(_)
{'type': 'bigint', 'value': '36893488147419103232'}
OPT_PASSTHROUGH_DATACLASS

dataclasses.dataclass 实例透传到 default。这允许自定义它们的输出,但速度较慢。

>>> import ormsgpack, dataclasses
>>> @dataclasses.dataclass
... class User:
...     id: str
...     name: str
...     password: str
...
>>> def default(obj):
...     if isinstance(obj, User):
...         return {"id": obj.id, "name": obj.name}
...     raise TypeError
...
>>> ormsgpack.packb(User("3b1", "asd", "zxc"))
b'\x83\xa2id\xa33b1\xa4name\xa3asd\xa8password\xa3zxc'
>>> ormsgpack.packb(User("3b1", "asd", "zxc"), option=ormsgpack.OPT_PASSTHROUGH_DATACLASS)
TypeError: Type is not msgpack serializable: User
>>> ormsgpack.packb(
...     User("3b1", "asd", "zxc"),
...     option=ormsgpack.OPT_PASSTHROUGH_DATACLASS,
...     default=default,
... )
b'\x82\xa2id\xa33b1\xa4name\xa3asd'
OPT_PASSTHROUGH_DATETIME

datetime.datetimedatetime.datedatetime.time 实例透传到 default。这允许将日期时间序列化到自定义格式,例如 HTTP 日期。

>>> import ormsgpack, datetime
>>> def default(obj):
...     if isinstance(obj, datetime.datetime):
...         return obj.strftime("%a, %d %b %Y %H:%M:%S GMT")
...     raise TypeError
...
>>> ormsgpack.packb({"created_at": datetime.datetime(1970, 1, 1)})
b'\x81\xaacreated_at\xb31970-01-01T00:00:00'
>>> ormsgpack.packb({"created_at": datetime.datetime(1970, 1, 1)}, option=ormsgpack.OPT_PASSTHROUGH_DATETIME)
TypeError: Type is not msgpack serializable: datetime.datetime
>>> ormsgpack.packb(
...     {"created_at": datetime.datetime(1970, 1, 1)},
...     option=ormsgpack.OPT_PASSTHROUGH_DATETIME,
...     default=default,
... )
b'\x81\xaacreated_at\xbdThu, 01 Jan 1970 00:00:00 GMT'

如果使用 OPT_NON_STR_KEYS,则此选项不影响 dict 键中的日期时间。

OPT_PASSTHROUGH_SUBCLASS

将内置类型的子类透传到 default

>>> import ormsgpack
>>> class Secret(str):
...     pass
...
>>> def default(obj):
...     if isinstance(obj, Secret):
...         return "******"
...     raise TypeError
...
>>> ormsgpack.packb(Secret("zxc"))
b'\xa3zxc'
>>> ormsgpack.packb(Secret("zxc"), option=ormsgpack.OPT_PASSTHROUGH_SUBCLASS)
TypeError: Type is not msgpack serializable: Secret
>>> ormsgpack.packb(Secret("zxc"), option=ormsgpack.OPT_PASSTHROUGH_SUBCLASS, default=default)
b'\xa6******'

如果使用 OPT_NON_STR_KEYS,则此选项不影响将子类序列化为 dict 键。

OPT_PASSTHROUGH_TUPLE

将元组透传到 default

>>> import ormsgpack
>>> ormsgpack.packb(
...     (9193, "test", 42),
... )
b'\x93\xcd#\xe9\xa4test*'
>>> ormsgpack.unpackb(_)
[9193, 'test', 42]
>>> ormsgpack.packb(
...     (9193, "test", 42),
...     option=ormsgpack.OPT_PASSTHROUGH_TUPLE,
...     default=lambda _: {"type": "tuple", "value": list(_)}
... )
b'\x82\xa4type\xa5tuple\xa5value\x93\xcd#\xe9\xa4test*'
>>> ormsgpack.unpackb(_)
{'type': 'tuple', 'value': [9193, 'test', 42]}
OPT_SERIALIZE_NUMPY

序列化 numpy.ndarray 实例。更多内容请参阅 numpy

OPT_SERIALIZE_PYDANTIC

序列化 pydantic.BaseModel 实例。

OPT_SORT_KEYS

按排序顺序序列化 dict 键。默认情况下,序列化顺序未指定。

这可以用来确保顺序在散列或测试中是确定的。它具有相当大的性能惩罚,并且通常不推荐使用。

>>> import ormsgpack
>>> ormsgpack.packb({"b": 1, "c": 2, "a": 3})
b'\x83\xa1b\x01\xa1c\x02\xa1a\x03'
>>> ormsgpack.packb({"b": 1, "c": 2, "a": 3}, option=ormsgpack.OPT_SORT_KEYS)
b'\x83\xa1a\x03\xa1b\x01\xa1c\x02'

排序不是排序/区域感知的

>>> import ormsgpack
>>> ormsgpack.packb({"a": 1, "ä": 2, "A": 3}, option=ormsgpack.OPT_SORT_KEYS)
b'\x83\xa1A\x03\xa1a\x01\xa2\xc3\xa4\x02'

dataclass 也序列化为映射,但这不会对它们产生影响。

OPT_UTC_Z

datetime.datetimenumpy.datetime64 实例上的 UTC 时区序列化为 Z 而不是 +00:00

>>> import ormsgpack, datetime
>>> ormsgpack.packb(
...     datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc),
... )
b'\xb91970-01-01T00:00:00+00:00'
>>> ormsgpack.packb(
...     datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc),
...     option=ormsgpack.OPT_UTC_Z
... )
b'\xb41970-01-01T00:00:00Z'

反序列化

def unpackb(
    __obj: Union[bytes, bytearray, memoryview],
    /,
    ext_hook: Optional[Callable[[int, bytes], Any]] = ...,
    option: Optional[int] = ...,
) -> Any: ...

unpackb() 将 msgpack 反序列化为 Python 对象。它将反序列化为 dictlistintfloatstrboolbytesNone 对象。

接受 bytesbytearraymemoryview 输入。

ormsgpack 在整个过程中维护一个映射键的缓存。这通过避免重复字符串来减少内存使用。键的最大长度为 64 字节,存储 512 个条目。

在调用期间保持全局解释器锁 (GIL)。

如果给定的类型无效或无效的 msgpack,将引发 MsgpackDecodeError

MsgpackDecodeErrorValueError 的子类。

ext_hook

为了反序列化扩展类型,指定可选的 ext_hook 参数。值应该是可调用的,并且将使用扩展类型和值作为参数调用它。

>>> import ormsgpack, decimal
>>> def ext_hook(tag, data):
...     if tag == 0:
...         return decimal.Decimal(data.decode())
...     raise TypeError
...
>>> ormsgpack.packb(
...     ormsgpack.Ext(0, str(decimal.Decimal("0.0842389659712649442845")).encode())
... )
b'\xc7\x18\x000.0842389659712649442845'
>>> ormsgpack.unpackb(_, ext_hook=ext_hook)
Decimal('0.0842389659712649442845'

选项

unpackb() 支持了 OPT_NON_STR_KEYS 选项,这类似于原始 msgpack 的 strict_map_key=False。请注意,此选项被认为是不安全的,并且默认在 msgpack 中禁用,因为存在 HashDoS 的可能性。

类型

dataclass

ormsgpack 本地序列化 dataclasses.dataclass 实例。它的序列化速度比其他库快 40-50 倍,并且避免了与其他库相比序列化 dict 时出现的严重减速。

支持传递所有变体的数据类,包括使用 __slots__ 的数据类、冻结数据类、具有可选或默认属性的数据类以及子类。不使用 __slots__ 有性能优势。

数据类作为映射序列化,每个属性都按类定义中给出的顺序序列化

>>> import dataclasses, ormsgpack, typing
>>> @dataclasses.dataclass
... class Member:
...     id: int
...     active: bool = dataclasses.field(default=False)
...
>>> @dataclasses.dataclass
... class Object:
...     id: int
...     name: str
...     members: typing.List[Member]
...
>>> ormsgpack.packb(Object(1, "a", [Member(1, True), Member(2)]))
b'\x83\xa2id\x01\xa4name\xa1a\xa7members\x92\x82\xa2id\x01\xa6active\xc3\x82\xa2id\x02\xa6active\xc2'

性能

alt text

--------------------------------------------------------------------------------- benchmark 'dataclass': 2 tests --------------------------------------------------------------------------------
Name (time in ms)                 Min                 Max                Mean            StdDev              Median               IQR            Outliers       OPS            Rounds  Iterations
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_dataclass_ormsgpack       3.4248 (1.0)        7.7949 (1.0)        3.6266 (1.0)      0.3293 (1.0)        3.5815 (1.0)      0.0310 (1.0)          4;34  275.7434 (1.0)         240           1
test_dataclass_msgpack       140.2774 (40.96)    143.6087 (18.42)    141.3847 (38.99)    1.0038 (3.05)     141.1823 (39.42)    0.7304 (23.60)         2;1    7.0729 (0.03)          8           1
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

datetime

ormsgpack 将 datetime.datetime 对象序列化为 RFC 3339 格式,例如,"1970-01-01T00:00:00+00:00"。这是 ISO 8601 的子集,并且与标准库中的 isoformat() 兼容。

>>> import ormsgpack, datetime, zoneinfo
>>> ormsgpack.packb(
...     datetime.datetime(2018, 12, 1, 2, 3, 4, 9, tzinfo=zoneinfo.ZoneInfo('Australia/Adelaide'))
... )
b'\xd9 2018-12-01T02:03:04.000009+10:30'
>>> ormsgpack.unpackb(_)
'2018-12-01T02:03:04.000009+10:30'
>>> ormsgpack.packb(
...     datetime.datetime.fromtimestamp(4123518902).replace(tzinfo=datetime.timezone.utc)
... )
b'\xb92100-09-02T00:55:02+00:00'
>>> ormsgpack.unpackb(_)
'2100-09-02T00:55:02+00:00'
>>> ormsgpack.packb(
...     datetime.datetime.fromtimestamp(4123518902)
... )
b'\xb32100-09-02T00:55:02'
>>> ormsgpack.unpackb(_)
'2100-09-02T00:55:02'

datetime.datetime 支持具有以下 tzinfo 的实例:Nonedatetime.timezone.utc、python3.9+ 的 zoneinfo 模块中的时区实例,或第三方 pendulumpytzdateutil/arrow 库中的时区实例。

datetime.time 对象不得有 tzinfo

>>> import ormsgpack, datetime
>>> ormsgpack.packb(datetime.time(12, 0, 15, 290))
b'\xaf12:00:15.000290'
>>> ormsgpack.unpackb(_)
'12:00:15.000290'

datetime.date 对象将始终序列化。

>>> import ormsgpack, datetime
>>> ormsgpack.packb(datetime.date(1900, 1, 2))
b'\xaa1900-01-02'
>>> ormsgpack.unpackb(_)
'1900-01-02'

具有 tzinfo 的错误会导致引发 MsgpackEncodeError

要禁用 datetime 对象的序列化,指定选项 ormsgpack.OPT_PASSTHROUGH_DATETIME

要使用 "Z" 后缀而不是 "+00:00" 来表示 UTC ("Zulu") 时间,使用选项 ormsgpack.OPT_UTC_Z

要假设没有时区的日期时间都是 UTC,使用选项 ormsgpack.OPT_NAIVE_UTC

enum

ormsgpack 本地序列化枚举。选项适用于它们的值。

>>> import enum, datetime, ormsgpack
>>> class DatetimeEnum(enum.Enum):
...     EPOCH = datetime.datetime(1970, 1, 1, 0, 0, 0)
...
>>> ormsgpack.packb(DatetimeEnum.EPOCH)
b'\xb31970-01-01T00:00:00'
>>> ormsgpack.unpackb(_)
'1970-01-01T00:00:00'
>>> ormsgpack.packb(DatetimeEnum.EPOCH, option=ormsgpack.OPT_NAIVE_UTC)
b'\xb91970-01-01T00:00:00+00:00'
>>> ormsgpack.unpackb(_)
'1970-01-01T00:00:00+00:00'

具有不受支持类型成员的枚举可以使用 default 进行序列化

>>> import enum, ormsgpack
>>> class Custom:
...     def __init__(self, val):
...         self.val = val
...
>>> def default(obj):
...     if isinstance(obj, Custom):
...         return obj.val
...     raise TypeError
...
>>> class CustomEnum(enum.Enum):
...     ONE = Custom(1)
...
>>> ormsgpack.packb(CustomEnum.ONE, default=default)
b'\x01'
>>> ormsgpack.unpackb(_)
1

float

ormsgpack 无损且一致地序列化和反序列化双精度浮点数。

int

ormsgpack 默认序列化和反序列化 64 位整数。支持的范围内是一个有符号 64 位整数的最小值 (-9223372036854775807) 到一个无符号 64 位整数的最大值 (18446744073709551615)。

numpy

ormsgpack 本地序列化 numpy.ndarray 以及单个 numpy.float64numpy.float32numpy.float16numpy.int64numpy.int32numpy.int16numpy.int8numpy.uint64numpy.uint32numpy.uint16numpy.uint8numpy.uintpnumpy.intpnumpy.datetime64numpy.bool 实例。

numpy.datetime64 实例被序列化为 RFC 3339 字符串。

ormsgpack 在序列化 numpy 实例方面比所有比较的库都要快。序列化 numpy 数据需要指定 option=ormsgpack.OPT_SERIALIZE_NUMPY

>>> import ormsgpack, numpy
>>> ormsgpack.packb(
...     numpy.array([[1, 2, 3], [4, 5, 6]]),
...     option=ormsgpack.OPT_SERIALIZE_NUMPY,
... )
b'\x92\x93\x01\x02\x03\x93\x04\x05\x06'
>>> ormsgpack.unpackb(_)
[[1, 2, 3], [4, 5, 6]]

数组必须是连续的 C 数组(C_CONTIGUOUS)并且是支持的数据类型之一。

如果数组不是连续的 C 数组或包含不受支持的数据类型,ormsgpack 将回退到 default。在 default 中,可以指定 obj.tolist()。如果数组格式不正确,则不会期望这种情况,将引发 ormsgpack.MsgpackEncodeError

性能

alt text alt text alt text alt text alt text

---------------------------------------------------------------------------------- benchmark 'numpy float64': 2 tests ---------------------------------------------------------------------------------
Name (time in ms)                      Min                 Max                Mean             StdDev              Median                IQR            Outliers      OPS            Rounds  Iterations
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_numpy_ormsgpack[float64]      77.9625 (1.0)       85.2507 (1.0)       79.0326 (1.0)       1.9043 (1.0)       78.5505 (1.0)       0.7408 (1.0)           1;1  12.6530 (1.0)          13           1
test_numpy_msgpack[float64]       511.5176 (6.56)     606.9395 (7.12)     559.0017 (7.07)     44.0661 (23.14)    572.5499 (7.29)     81.2972 (109.75)        3;0   1.7889 (0.14)          5           1
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


------------------------------------------------------------------------------------- benchmark 'numpy int32': 2 tests -------------------------------------------------------------------------------------
Name (time in ms)                      Min                   Max                  Mean             StdDev                Median                IQR            Outliers     OPS            Rounds  Iterations
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_numpy_ormsgpack[int32]       197.8751 (1.0)        210.3111 (1.0)        201.1033 (1.0)       5.1886 (1.0)        198.8518 (1.0)       3.8297 (1.0)           1;1  4.9726 (1.0)           5           1
test_numpy_msgpack[int32]       1,363.8515 (6.89)     1,505.4747 (7.16)     1,428.2127 (7.10)     53.4176 (10.30)    1,425.3516 (7.17)     72.8064 (19.01)         2;0  0.7002 (0.14)          5           1
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


-------------------------------------------------------------------------------- benchmark 'numpy int8': 2 tests ---------------------------------------------------------------------------------
Name (time in ms)                   Min                 Max                Mean            StdDev              Median                IQR            Outliers     OPS            Rounds  Iterations
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_numpy_ormsgpack[int8]     107.8013 (1.0)      113.7336 (1.0)      109.0364 (1.0)      1.7805 (1.0)      108.3574 (1.0)       0.4066 (1.0)           1;2  9.1712 (1.0)          10           1
test_numpy_msgpack[int8]       685.4149 (6.36)     703.2958 (6.18)     693.2396 (6.36)     7.9572 (4.47)     691.5435 (6.38)     14.4142 (35.45)         1;0  1.4425 (0.16)          5           1
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


------------------------------------------------------------------------------------- benchmark 'numpy npbool': 2 tests --------------------------------------------------------------------------------------
Name (time in ms)                       Min                   Max                  Mean             StdDev                Median                IQR            Outliers      OPS            Rounds  Iterations
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_numpy_ormsgpack[npbool]        87.9005 (1.0)         89.5460 (1.0)         88.7928 (1.0)       0.5098 (1.0)         88.8508 (1.0)       0.6609 (1.0)           4;0  11.2622 (1.0)          12           1
test_numpy_msgpack[npbool]       1,095.0599 (12.46)    1,176.3442 (13.14)    1,120.5916 (12.62)    32.9993 (64.73)    1,110.4216 (12.50)    38.4189 (58.13)         1;0   0.8924 (0.08)          5           1
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


--------------------------------------------------------------------------------- benchmark 'numpy uint8': 2 tests ---------------------------------------------------------------------------------
Name (time in ms)                    Min                 Max                Mean             StdDev              Median                IQR            Outliers     OPS            Rounds  Iterations
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_numpy_ormsgpack[uint8]     133.1743 (1.0)      134.7246 (1.0)      134.2793 (1.0)       0.4946 (1.0)      134.3120 (1.0)       0.4492 (1.0)           1;1  7.4472 (1.0)           8           1
test_numpy_msgpack[uint8]       727.1393 (5.46)     824.8247 (6.12)     775.7032 (5.78)     34.9887 (70.73)    775.9595 (5.78)     36.2824 (80.78)         2;0  1.2892 (0.17)          5           1
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

uuid

ormsgpack 将 uuid.UUID 实例序列化为 RFC 4122 格式,例如,"f81d4fae-7dec-11d0-a765-00a0c91e6bf6"。

>>> import ormsgpack, uuid
>>> ormsgpack.packb(uuid.UUID('f81d4fae-7dec-11d0-a765-00a0c91e6bf6'))
b'\xd9$f81d4fae-7dec-11d0-a765-00a0c91e6bf6'
>>> ormsgpack.unpackb(_)
'f81d4fae-7dec-11d0-a765-00a0c91e6bf6'
>>> ormsgpack.packb(uuid.uuid5(uuid.NAMESPACE_DNS, "python.org"))
b'\xd9$886313e1-3b8a-5372-9b90-0c9aee199e5d'
>>> ormsgpack.unpackb(_)
'886313e1-3b8a-5372-9b90-0c9aee199e5d

Pydantic

ormsgpack 本地序列化 pydantic.BaseModel 实例。

性能

alt text

-------------------------------------------------------------------------------- benchmark 'pydantic': 2 tests ---------------------------------------------------------------------------------
Name (time in ms)                Min                 Max                Mean            StdDev              Median               IQR            Outliers       OPS            Rounds  Iterations
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_pydantic_ormsgpack       4.3918 (1.0)       12.6521 (1.0)        4.8550 (1.0)      1.1455 (3.98)       4.6101 (1.0)      0.0662 (1.0)         11;24  205.9727 (1.0)         204           1
test_pydantic_msgpack       124.5500 (28.36)    125.5427 (9.92)     125.0582 (25.76)    0.2877 (1.0)      125.0855 (27.13)    0.2543 (3.84)          2;0    7.9963 (0.04)          8           1
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

延迟

图形

alt text alt text alt text alt text alt text alt text alt text alt text

数据

----------------------------------------------------------------------------- benchmark 'canada packb': 2 tests ------------------------------------------------------------------------------
Name (time in ms)                   Min                Max              Mean            StdDev            Median               IQR            Outliers       OPS            Rounds  Iterations
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_ormsgpack_packb[canada]     3.5302 (1.0)       3.8939 (1.0)      3.7319 (1.0)      0.0563 (1.0)      3.7395 (1.0)      0.0484 (1.0)         56;22  267.9571 (1.0)         241           1
test_msgpack_packb[canada]       8.8642 (2.51)     14.0432 (3.61)     9.3660 (2.51)     0.5649 (10.03)    9.2983 (2.49)     0.0982 (2.03)         3;11  106.7691 (0.40)        106           1
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


------------------------------------------------------------------------------- benchmark 'canada unpackb': 2 tests --------------------------------------------------------------------------------
Name (time in ms)                      Min                Max               Mean             StdDev             Median                IQR            Outliers      OPS            Rounds  Iterations
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_msgpack_unpackb[canada]       10.1176 (1.0)      62.0466 (1.18)     33.4806 (1.0)      18.8279 (1.0)      46.6582 (1.0)      38.5921 (1.02)         30;0  29.8680 (1.0)          67           1
test_ormsgpack_unpackb[canada]     11.3992 (1.13)     52.6587 (1.0)      34.1842 (1.02)     18.9461 (1.01)     47.6456 (1.02)     37.8024 (1.0)           8;0  29.2533 (0.98)         20           1
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


----------------------------------------------------------------------------- benchmark 'citm_catalog packb': 2 tests -----------------------------------------------------------------------------
Name (time in ms)                         Min               Max              Mean            StdDev            Median               IQR            Outliers       OPS            Rounds  Iterations
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_ormsgpack_packb[citm_catalog]     1.8024 (1.0)      2.1259 (1.0)      1.9487 (1.0)      0.0346 (1.0)      1.9525 (1.0)      0.0219 (1.0)         79;60  513.1650 (1.0)         454           1
test_msgpack_packb[citm_catalog]       3.4195 (1.90)     3.8128 (1.79)     3.6928 (1.90)     0.0535 (1.55)     3.7009 (1.90)     0.0250 (1.14)        47;49  270.7958 (0.53)        257           1
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


------------------------------------------------------------------------------ benchmark 'citm_catalog unpackb': 2 tests ------------------------------------------------------------------------------
Name (time in ms)                           Min                Max               Mean             StdDev            Median               IQR            Outliers      OPS            Rounds  Iterations
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_ormsgpack_unpackb[citm_catalog]     5.6986 (1.0)      46.1843 (1.0)      14.2491 (1.0)      15.9791 (1.0)      6.1051 (1.0)      0.3074 (1.0)           5;5  70.1798 (1.0)          23           1
test_msgpack_unpackb[citm_catalog]       7.2600 (1.27)     56.6642 (1.23)     16.4095 (1.15)     16.3257 (1.02)     7.7364 (1.27)     0.4944 (1.61)        28;29  60.9404 (0.87)        125           1
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


----------------------------------------------------------------------------------- benchmark 'github packb': 2 tests -----------------------------------------------------------------------------------
Name (time in us)                     Min                 Max                Mean            StdDev              Median               IQR            Outliers  OPS (Kops/s)            Rounds  Iterations
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_ormsgpack_packb[github]      73.0000 (1.0)      215.9000 (1.0)       80.4826 (1.0)      4.8889 (1.0)       80.3000 (1.0)      1.1000 (1.83)     866;1118       12.4250 (1.0)        6196           1
test_msgpack_packb[github]       103.8000 (1.42)     220.8000 (1.02)     112.8049 (1.40)     4.9686 (1.02)     113.0000 (1.41)     0.6000 (1.0)     1306;1560        8.8649 (0.71)       7028           1
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


----------------------------------------------------------------------------------- benchmark 'github unpackb': 2 tests -----------------------------------------------------------------------------------
Name (time in us)                       Min                 Max                Mean            StdDev              Median               IQR            Outliers  OPS (Kops/s)            Rounds  Iterations
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_ormsgpack_unpackb[github]     201.3000 (1.0)      318.5000 (1.0)      219.0861 (1.0)      6.7340 (1.0)      219.1000 (1.0)      1.2000 (1.0)       483;721        4.5644 (1.0)        3488           1
test_msgpack_unpackb[github]       289.8000 (1.44)     436.0000 (1.37)     314.9631 (1.44)     9.4130 (1.40)     315.1000 (1.44)     2.3000 (1.92)      341;557        3.1750 (0.70)       2477           1
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------- benchmark 'twitter packb': 2 tests ---------------------------------------------------------------------------------------
Name (time in us)                        Min                   Max                  Mean             StdDev                Median                IQR            Outliers         OPS            Rounds  Iterations
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_ormsgpack_packb[twitter]       820.7000 (1.0)      2,945.2000 (2.03)       889.3791 (1.0)      78.4139 (2.43)       884.2000 (1.0)      12.5250 (1.0)          4;76  1,124.3799 (1.0)         809           1
test_msgpack_packb[twitter]       1,209.3000 (1.47)     1,451.2000 (1.0)      1,301.3615 (1.46)     32.2147 (1.0)      1,306.7000 (1.48)     14.1000 (1.13)      118;138    768.4260 (0.68)        592           1
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


------------------------------------------------------------------------------ benchmark 'twitter unpackb': 2 tests -----------------------------------------------------------------------------
Name (time in ms)                      Min                Max              Mean            StdDev            Median               IQR            Outliers       OPS            Rounds  Iterations
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_ormsgpack_unpackb[twitter]     2.7097 (1.0)      41.1530 (1.0)      3.2721 (1.0)      3.5860 (1.03)     2.8868 (1.0)      0.0614 (1.32)         4;38  305.6098 (1.0)         314           1
test_msgpack_unpackb[twitter]       3.8079 (1.41)     42.0617 (1.02)     4.4459 (1.36)     3.4893 (1.0)      4.1097 (1.42)     0.0465 (1.0)          2;54  224.9267 (0.74)        228           1
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

重现

上述测试使用 Python 3.7.9 在 Azure Linux VM (x86_64) 上进行,使用 ormsgpack 0.2.1 和 msgpack 1.0.2。

可以使用 ./scripts/benchmark.sh 重现延迟结果,并使用 pytest --benchmark-histogram benchmarks/bench_* 生成图形。

问题

为什么我不能从 PyPI 安装它?

可能需要将 pip 升级到版本 20.3 或更高版本,以支持最新的 manylinux_x_y 或 universal2 轮子格式。

它是否可以将数据类、UUID、小数等反序列化或支持 object_hook?

不行。这需要指定一个模式,说明期望哪些类型以及如何处理错误等。这由一级以上的数据验证库解决。

打包

要将ormspack打包,需要Rust 1.65或更高版本以及Rustmaturin构建工具。默认功能unstable-simd启用SIMD操作,需要nightly Rust。推荐的构建命令是

maturin build --release --strip

ormsgpack已在Linux/amd64、Linux/aarch64、Linux/armv7、macOS/amd64和Windows/amd64上进行测试。

除了libc之外,没有其他运行时依赖。

许可证

orjson由ijl ijl@mailbox.org 编写,版权所有 2018 - 2021,同时遵循Apache 2和MIT许可证。

ormsgpack是从orjson分支出来的,由Aviram Hassan维护,由Emanuele Giaquinta (@exg) 维护,许可方式与orjson相同。

项目详情


下载文件

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

源分布

ormsgpack-1.5.0.tar.gz (54.4 kB 查看散列)

上传时间

构建分布

ormsgpack-1.5.0-cp312-none-win_amd64.whl (155.2 kB 查看散列)

上传时间 CPython 3.12 Windows x86-64

ormsgpack-1.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (276.6 kB 查看散列)

上传时间 CPython 3.12 manylinux: glibc 2.17+ x86-64

ormsgpack-1.5.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (280.7 kB 查看散列)

上传时间 CPython 3.12 manylinux: glibc 2.17+ ARMv7l

ormsgpack-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (276.9 kB 查看散列)

上传时间 CPython 3.12 manylinux: glibc 2.17+ ARM64

或msgpack-1.5.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (427.4 kB 查看哈希值)

上传时间 CPython 3.12 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64

或msgpack-1.5.0-cp311-none-win_amd64.whl (154.9 kB 查看哈希值)

上传时间 CPython 3.11 Windows x86-64

或msgpack-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (276.1 kB 查看哈希值)

上传时间 CPython 3.11 manylinux: glibc 2.17+ x86-64

或msgpack-1.5.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (280.6 kB 查看哈希值)

上传时间 CPython 3.11 manylinux: glibc 2.17+ ARMv7l

或msgpack-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (276.8 kB 查看哈希值)

上传时间 CPython 3.11 manylinux: glibc 2.17+ ARM64

或msgpack-1.5.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (426.6 kB 查看哈希值)

上传时间 CPython 3.11 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64

或msgpack-1.5.0-cp310-none-win_amd64.whl (154.9 kB 查看哈希值)

上传时间 CPython 3.10 Windows x86-64

或msgpack-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (276.1 kB 查看哈希值)

上传时间 CPython 3.10 manylinux: glibc 2.17+ x86-64

或msgpack-1.5.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (280.6 kB 查看哈希值)

上传时间 CPython 3.10 manylinux: glibc 2.17+ ARMv7l

或msgpack-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (276.8 kB 查看哈希)

上传时间: CPython 3.10 manylinux: glibc 2.17+ ARM64

或msgpack-1.5.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (426.6 kB 查看哈希)

上传时间: CPython 3.10 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64

或msgpack-1.5.0-cp39-none-win_amd64.whl (154.9 kB 查看哈希)

上传时间: CPython 3.9 Windows x86-64

或msgpack-1.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (276.1 kB 查看哈希)

上传时间: CPython 3.9 manylinux: glibc 2.17+ x86-64

或msgpack-1.5.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (280.6 kB 查看哈希)

上传时间: CPython 3.9 manylinux: glibc 2.17+ ARMv7l

或msgpack-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (276.8 kB 查看哈希)

上传时间: CPython 3.9 manylinux: glibc 2.17+ ARM64

或msgpack-1.5.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (426.6 kB 查看哈希)

上传时间: CPython 3.9 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64

或msgpack-1.5.0-cp38-none-win_amd64.whl (154.9 kB 查看哈希)

上传时间: CPython 3.8 Windows x86-64

或msgpack-1.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (276.0 kB 查看哈希)

上传时间: CPython 3.8 manylinux: glibc 2.17+ x86-64

或msgpack-1.5.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (280.6 kB 查看哈希)

上传时间: CPython 3.8 manylinux: glibc 2.17+ ARMv7l

或msgpack-1.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (276.7 kB 查看哈希值)

上传时间: CPython 3.8 manylinux: glibc 2.17+ ARM64

或msgpack-1.5.0-cp38-cp38-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (426.6 kB 查看哈希值)

上传时间: CPython 3.8 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64

支持者