当前位置:首页>python>Python 高性能 JSON 方案:orjson(比内置库快 8-10 倍)实操指南

Python 高性能 JSON 方案:orjson(比内置库快 8-10 倍)实操指南

  • 2026-10-21 13:29:56
Python 高性能 JSON 方案:orjson(比内置库快 8-10 倍)实操指南

orjson 是一款基于 Rust 开发的 Python JSON 序列化/反序列化库,核心优势是性能优于内置 json 库,且原生支持多种常用数据类型,无需额外编写适配代码。

版本说明:本文基于 orjson 3.11.5,Python 3.13.0。

1. orjson 与内置 json 库的差异

先明确 orjson 的定位——它不是“全能神器”,而是“在特定场景下更高效的替代工具”。和 Python 内置 json 库相比,核心差异如下:

  • 性能:官方实测及实际项目验证,dumps 序列化速度约为内置 json 的 8~10 倍,loads 反序列化速度约为 2 倍;大数据量(100KB 以上)或高频序列化场景(如接口返回、日志写入),优势更明显,小数据量场景差异感知不强。

  • 返回类型:orjson.dumps 返回 bytes 类型,内置 json.dumps 返回 str 类型;bytes 在文件 IO、网络传输场景下无需二次编码,更省内存。

  • 原生类型支持:无需自定义编码器,直接序列化 datetime、date、time、UUID、dataclass、numpy 数组等,内置 json 库对这些类型会直接报错。

  • 功能精简:无 dump/load 方法(不能直接操作文件流),需通过原生文件 IO 替代;不支持序列化 lambda、生成器等不可哈希对象,符合 JSON 标准规范。

适用场景:接口开发、日志采集、大数据处理、AI 数据序列化(numpy 场景);

非必要场景:简单小数据序列化(用内置 json 更省心)。

2. 环境安装与版本验证

2.1 安装命令

orjson 无额外依赖,全平台(Windows/macOS/Linux)支持,通过 pip 安装即可:


# 安装最新稳定版(3.10.0)
pip install -U orjson

2.2 版本验证

安装后执行以下代码,确认版本正确:

import orjson
print(orjson.__version__) 

本例显示:

3.11.5

3. 核心 API 详解

orjson 核心 API 仅 2 个,用法和内置 json 库高度一致,上手成本极低,重点掌握参数细节即可。

3.1 序列化:

函数:

orjson.dumps(obj, *, default=None, option=0)`

功能:将 Python 对象转为 JSON 格式的 bytes 数据。

参数说明:

  • obj:必填,待序列化的 Python 对象(基础类型、高级类型均可,不支持不可序列化对象如 lambda)。

  • default:可选,兜底回调函数。当遇到 orjson 无法原生序列化的类型(如 set)时触发,需在函数中返回可序列化格式(如 list),无特殊类型时极少用到。

  • option:可选,核心配置参数,通过预定义常量控制序列化行为,支持多标志组合(按位或 | 连接),是 orjson 的核心实用功能。

3.2 反序列化

函数:

orjson.loads(s, *, strict=True)

功能:将 JSON 格式的 bytes/str 数据转为 Python 对象。

参数说明

  • s:必填,JSON 数据,支持 bytes、bytearray、str 三种类型(推荐传 bytes,性能更高)。

  • strict:可选,默认 True,严格遵循 JSON 标准,拒绝非法 JSON 字符(如未闭合引号);非必要不关闭(关闭可能导致数据解析异常)。

3.3 核心配置标志(option)

orjson 预定义了多个标志,用于控制序列化行为,以下是工作中高频用到的配置标志:

标志常量
功能说明
适用场景
OPT_INDENT_2
格式化输出 JSON,缩进 2 个空格,提升可读性
开发调试、日志写入
OPT_SORT_KEYS
序列化字典时,按 key 升序排序
接口返回一致性、日志对比
OPT_SERIALIZE_DATACLASS
原生序列化 dataclass 数据类
后端接口数据封装、数据传输
OPT_SERIALIZE_NUMPY
原生序列化 numpy 数组/矩阵
AI、数据科学场景
OPT_OMIT_MICROSECONDS
序列化 datetime 时省略微秒
不需要高精度时间的业务场景
OPT_ALLOW_NAN
允许序列化 nan、inf、-inf 特殊浮点值
科学计算、数值分析场景
标志组合用法:用按位或
连接多个标志,示例:格式化输出 + 排序 key + 序列化 dataclass → option=orjson.OPT_INDENT_2
orjson.OPT_SORT_KEYS

4. 分场景实操示例

4.1 基础类型序列化/反序列化

覆盖 dict、list、int、float、str、bool、None 等基础类型,和内置 json 用法一致:


import orjson

# 基础数据
data = {
"name": "张三",
"age": 28,
"is_active": True,
"score": 89.5,
"hobbies": ["阅读", "编程"],
"address": None,
"tags": ("技术", "后端")  # tuple 序列化后转为 list(JSON 标准无 tuple 类型)
}

# 序列化(返回 bytes)
json_bytes = orjson.dumps(data)
print("序列化结果(bytes):", json_bytes)
# 按需转为 str(接口返回、打印时用)
json_str = json_bytes.decode("utf-8")
print("序列化结果(str):", json_str)

# 反序列化(支持 bytes/str)
python_data = orjson.loads(json_bytes)
print("反序列化结果:", python_data)
print("类型验证:", type(python_data["hobbies"]))  # <class 'list'>

本例输出:

序列化结果(bytes): b'{"name":"\xe5\xbc\xa0\xe4\xb8\x89","age":28,"is_active":true,"score":89.5,"hobbies":["\xe9\x98\x85\xe8\xaf\xbb","\xe7\xbc\x96\xe7\xa8\x8b"],"address":null,"tags":["\xe6\x8a\x80\xe6\x9c\xaf","\xe5\x90\x8e\xe7\xab\xaf"]}'
序列化结果(str): {"name":"张三","age":28,"is_active":true,"score":89.5,"hobbies":["阅读","编程"],"address":null,"tags":["技术","后端"]}
反序列化结果: {'name': '张三', 'age': 28, 'is_active': True, 'score': 89.5, 'hobbies': ['阅读', '编程'], 'address': None, 'tags': ['技术', '后端']}
类型验证: <class 'list'>
(orjson-test) PS D:\learning\Python\orjson-test> python .\test2.py
默认序列化: {"create_time":"2026-01-11T21:23:35.126625","expire_date":"2026-01-11"}
精简序列化: {
"create_time": "2026-01-11T21:23:35",
"expire_date": "2026-01-11"
}

4.2 datetime/date 类型序列化

内置 json 库序列化 datetime 会报错,orjson 原生支持,无需自定义编码器:


import orjson
from datetime import datetime, date

data = {
"create_time": datetime.now(),  # 带微秒的datetime
"expire_date": date.today()     # date类型
}

# 默认序列化(保留微秒)
json1 = orjson.dumps(data)
print("默认序列化:", json1.decode("utf-8"))

# 省略微秒 + 格式化输出
json2 = orjson.dumps(
    data,
    option=orjson.OPT_INDENT_2 | orjson.OPT_OMIT_MICROSECONDS
)
print("精简序列化:", json2.decode("utf-8"))

本例输出:

默认序列化: {"create_time":"2026-01-11T21:23:35.126625","expire_date":"2026-01-11"}
精简序列化: {
"create_time": "2026-01-11T21:23:35",
"expire_date": "2026-01-11"
}

4.3 dataclass 序列化(后端开发常用)

开启 OPT_SERIALIZE_DATACLASS 标志,直接序列化 dataclass 对象,无需手动转字典:


import orjson
from dataclasses import dataclass

# 定义数据类(后端常用数据封装格式)
@dataclass
classUser:
    user_id: int
    username: str
    email: str
    is_vip: bool = False# 默认值

# 实例化
user1 = User(1001, "zhangsan", "zhangsan@test.com", True)
user2 = User(1002, "lisi", "lisi@test.com")

# 序列化(含列表)
data = {"total": 2, "users": [user1, user2]}
json_bytes = orjson.dumps(
    data,
    option=orjson.OPT_INDENT_2 | orjson.OPT_SERIALIZE_DATACLASS
)
print(json_bytes.decode("utf-8"))

本例输出:

{
"total": 2,
"users": [
    {
"user_id": 1001,
"username": "zhangsan",
"email": "zhangsan@test.com",
"is_vip": true
    },
    {
"user_id": 1002,
"username": "lisi",
"email": "lisi@test.com",
"is_vip": false
    }
  ]
}

4.4 numpy 数组序列化(数据科学场景)

开启 OPT_SERIALIZE_NUMPY 标志,直接序列化 numpy 数组,无需转 list:


import orjson
import numpy as np

# 构建numpy数据
data = {
"arr1": np.array([1, 2, 3, 4]),
"arr2": np.array([[1.1, 2.2], [3.3, 4.4]]),
"mean": np.mean([1, 2, 3])
}

# 序列化
json_bytes = orjson.dumps(
    data,
    option=orjson.OPT_INDENT_2 | orjson.OPT_SERIALIZE_NUMPY
)
print(json_bytes.decode("utf-8"))

本例输出:

{
"arr1": [
1,
2,
3,
4
  ],
"arr2": [
    [
1.1,
2.2
    ],
    [
3.3,
4.4
    ]
  ],
"mean": 2.0
}

4.5 文件读写 JSON 数据(替代 dump/load 方法)

orjson 无 dump/load 方法,通过二进制文件 IO 实现,性能比内置 json 的 dump/load 更高:


import orjson

# 待写入数据
data = [
    {"id": 1, "name": "orjson教程", "version": "3.10.0"},
    {"id": 2, "name": "实用案例", "type": "后端开发"}
]

# 写入文件(二进制模式 wb,推荐)
with open("json_data.json", "wb") as f:
    json_bytes = orjson.dumps(data, option=orjson.OPT_INDENT_2)
    f.write(json_bytes)

# 读取文件(二进制模式 rb,推荐)
with open("json_data.json", "rb") as f:
    json_bytes = f.read()
    data = orjson.loads(json_bytes)
    print("读取结果:", data)

本例输出:

读取结果: [{'id': 1, 'name': 'orjson教程', 'version': '3.10.0'}, {'id': 2, 'name': '实用案例', 'type': '后端开发'}]

4.6 特殊场景:处理 set 类型

orjson 无法原生序列化 set,通过 default 回调函数转为 list 处理:


import orjson

data = {
"name": "测试",
"tags": {"Python", "orjson"}  # set 类型,无法原生序列化
}

# 定义回调函数
defdefault_handler(obj):
if isinstance(obj, set):
return list(obj)  # 转为 list 序列化
# 其他无法序列化的类型,抛出异常提示
raise TypeError(f"不支持序列化类型:{type(obj)}")

# 序列化
json_bytes = orjson.dumps(
    data,
    default=default_handler,
    option=orjson.OPT_INDENT_2
)
print(json_bytes.decode("utf-8"))

本例输出:

{
"name": "测试",
"tags": [
"orjson",
"Python"
  ]
}

5. 模拟业务场景案例

5.1 项目需求

设计一个「用户行为日志采集」项目,模拟后端系统采集用户操作日志,用 orjson 序列化日志数据并写入文件,模拟真实工作场景,覆盖多知识点综合运用。

5.2 项目实现代码


import orjson
from dataclasses import dataclass
from datetime import datetime
from typing import List

# 1. 定义日志数据类
@dataclass
classUserActionLog:
    user_id: int
    username: str
    action_type: str  # 操作类型:login/logout/view/create
    action_time: datetime  # 操作时间
    action_detail: dict  # 操作详情
    ip_address: str  # 用户IP

# 2. 定义日志处理工具类
classLogProcessor:
def__init__(self, log_file_path: str):
        self.log_file_path = log_file_path  # 日志文件路径
# 配置orjson序列化选项:格式化+排序key+序列化dataclass+省略微秒
        self.option = orjson.OPT_INDENT_2 | orjson.OPT_SORT_KEYS | orjson.OPT_SERIALIZE_DATACLASS | orjson.OPT_OMIT_MICROSECONDS

defserialize_logs(self, logs: List[UserActionLog]) -> bytes:
"""序列化多条日志数据"""
return orjson.dumps(logs, option=self.option)

defwrite_logs(self, logs: List[UserActionLog]) -> None:
"""将日志写入文件(追加模式,避免覆盖)"""
        json_bytes = self.serialize_logs(logs)
# 二进制追加模式写入,每条日志后加换行符
with open(self.log_file_path, "ab") as f:
            f.write(json_bytes + b"\n")

# 3. 模拟日志采集与写入
if __name__ == "__main__":
# 初始化日志处理器,指定日志文件
    log_processor = LogProcessor("user_action.log")

# 模拟3条用户行为日志
    log1 = UserActionLog(
        user_id=1001,
        username="zhangsan",
        action_type="login",
        action_time=datetime.now(),
        action_detail={"device": "PC", "browser": "Chrome"},
        ip_address="192.168.1.100"
    )

    log2 = UserActionLog(
        user_id=1002,
        username="lisi",
        action_type="create",
        action_time=datetime.now(),
        action_detail={"resource": "article", "article_id": 5001},
        ip_address="192.168.1.101"
    )

    log3 = UserActionLog(
        user_id=1001,
        username="zhangsan",
        action_type="view",
        action_time=datetime.now(),
        action_detail={"resource": "article", "article_id": 5001},
        ip_address="192.168.1.100"
    )

# 批量写入日志
    log_processor.write_logs([log1, log2, log3])
    print("日志写入完成,可查看 user_action.log 文件")

5.3 项目知识点概要

  • dataclass 数据封装 + orjson 原生序列化;

  • 多 orjson 标志组合使用;

  • 二进制文件追加写入日志(贴合真实日志采集场景);

  • 面向对象封装(提升代码可维护性,符合工作规范)。

5.4 运行结果验证

运行代码后,会生成 user_action.log 文件,内容如下(格式化、有序、时间精简):

本例输出:

终端输出:

日志写入完成,可查看 user_action.log 文件

以下为 user_action.log 输出内容:

[
  {
"action_detail": {
"browser": "Chrome",
"device": "PC"
    },
"action_time": "2026-01-11 15:30:00",
"action_type": "login",
"ip_address": "192.168.1.100",
"user_id": 1001,
"username": "zhangsan"
  },
  {
"action_detail": {
"article_id": 5001,
"resource": "article"
    },
"action_time": "2026-01-11 15:30:00",
"action_type": "create",
"ip_address": "192.168.1.101",
"user_id": 1002,
"username": "lisi"
  },
  {
"action_detail": {
"article_id": 5001,
"resource": "article"
    },
"action_time": "2026-01-11 15:30:00",
"action_type": "view",
"ip_address": "192.168.1.100",
"user_id": 1001,
"username": "zhangsan"
  }
][
  {
"user_id": 1001,
"username": "zhangsan",
"action_type": "login",
"action_time": "2026-01-11T21:53:04",
"action_detail": {
"browser": "Chrome",
"device": "PC"
    },
"ip_address": "192.168.1.100"
  },
  {
"user_id": 1002,
"username": "lisi",
"action_type": "create",
"action_time": "2026-01-11T21:53:04",
"action_detail": {
"article_id": 5001,
"resource": "article"
    },
"ip_address": "192.168.1.101"
  },
  {
"user_id": 1001,
"username": "zhangsan",
"action_type": "view",
"action_time": "2026-01-11T21:53:04",
"action_detail": {
"article_id": 5001,
"resource": "article"
    },
"ip_address": "192.168.1.100"
  }
]

6. 常见问题

Q1:bytes 类型如何适配接口返回(如 FastAPI/Flask)?

大部分 Web 框架支持直接返回 bytes,或解码为 str 返回:


# FastAPI 示例
from fastapi import FastAPI
import orjson

app = FastAPI()

@app.get("/user")
asyncdefget_user():
    data = {"user_id": 1001, "name": "zhangsan"}
# 方式1:返回bytes(框架自动处理)
return orjson.dumps(data)
# 方式2:解码为str返回
# return orjson.dumps(data).decode("utf-8")

Q2:序列化 dataclass 时,如何忽略敏感字段(如密码)?

通过字典推导式过滤字段,或在 dataclass 中自定义序列化方法:


@dataclass
classUser:
    user_id: int
    username: str
    password: str  # 敏感字段,需忽略

user = User(1001, "zhangsan", "123456")
# 过滤敏感字段
filtered_data = {k: v for k, v in user.__dict__.items() if k != "password"}
json_bytes = orjson.dumps(filtered_data, option=orjson.OPT_INDENT_2)

Q3:orjson 序列化 datetime 时,时区信息如何保留?

开启 OPT_PASSTHROUGH_DATETIME 标志,同时确保 datetime 对象带时区信息:


import orjson
from datetime import datetime
import pytz  # 需要安装 pytz:pip install pytz

# 带时区的datetime
tz = pytz.timezone("Asia/Shanghai")
data = {"time": datetime.now(tz)}

# 保留时区序列化
json_bytes = orjson.dumps(
    data,
    option=orjson.OPT_INDENT_2 | orjson.OPT_PASSTHROUGH_DATETIME
)
print(json_bytes.decode("utf-8"))

Q4:Python 3.7 及以下版本如何使用 orjson?

orjson 3.11.5 不支持 Python 3.7 及以下,需安装旧版:pip install orjson==3.8.15(仅支持 Python 3.6~3.11)。

7. 小结

orjson 的核心价值的是「高性能序列化+原生支持多类型」,用法和内置 json 库高度兼容,学习成本低,落地场景明确。


作者简介:码上工坊,探索用编程为己赋能,定期分享编程知识和项目实战经验。持续学习、适应变化、记录点滴、复盘反思、成长进步。

重要提示:本文主要是记录自己的学习与实践过程,所提内容或者观点仅代表个人意见,只是我以为的,不代表完全正确,欢迎交流讨论。

最新文章

随机文章