orjson 与 json:实战对比与选型指南(含示例)(GPT-5 回答)

orjson 与 json:实战对比与选型指南(含示例)

结论先行

  • 性能:orjson 在序列化、反序列化上通常显著快于标准库 json,适合高吞吐/低延迟场景。
  • 易用性与依赖:json 零依赖、API 熟悉,默认选择依旧"够用",部署更简单。
  • 特性 :orjson 原生支持 dataclass、datetime、numpy、UUID 等类型,且严格 UTF-8 与 RFC 8259;但 dumps() 返回 bytes,缩进只支持 2 空格,部分行为需通过选项切换。

基本差异一览

  • 返回类型

    • json :json.dumps(obj) 返回 str
    • orjson :orjson.dumps(obj) 返回 bytes(UTF-8)。若你需要字符串,可 orjson.dumps(obj).decode("utf-8")
  • 性能(示意)

    • 多项对比中,orjson 在 dumps/loads 上均为领先者,常见场景可比标准库快数倍。
    • 参考:
      • orjson README 的性能说明("something like 10x as fast as json" 取决于数据与环境)
      • 社区基准示例:在 3M 次循环里,orjson 明显快于 json 与 ujson(见文末参考)
  • 编码与规范

    • orjson :严格 UTF-8 与 RFC 8259。输出始终为 UTF-8 字节序列,不支持将非 ASCII 字符转义为 \uXXXX。
    • json :默认 ensure_ascii=True,会把中文等非 ASCII 字符转成转义序列;若想直出 UTF-8,应 ensure_ascii=False。
  • 类型支持

    • orjson :原生序列化 dataclasses.dataclass、datetime/date/time、uuid.UUID、numpy.ndarray 等;也支持 enum、TypedDict 等。
    • json :遇到上述对象通常需要自定义 default 处理或手动转换。
  • 字典键(非字符串)

    • json :默认允许键是 str、int、float、bool 或 None(序列化时会转为字符串)。
    • orjson :默认仅允许 str 键;如需其它类型,需加 option=orjson.OPT_NON_STR_KEYS。
  • 整数与浮点

    • orjson :整数默认限制在 64 位;若开启 OPT_STRICT_INTEGER,限制为 53 位(与 JS Number 安全整数范围一致)。
    • json :对大整数更宽松(Python int 任意精度),但落地到 JS/数据库时仍需考虑精度问题。
  • Pretty Print(美化输出)

    • json :indent=N 任意缩进选择,sort_keys=True 排序。
    • orjson :仅提供 OPT_INDENT_2(固定 2 空格);排序使用 OPT_SORT_KEYS。
  • 运行时/平台支持

    • orjson:需额外依赖,提供多平台 wheel;不支持 PyPy。某些极简/受限环境可能安装困难。
    • json:标准库,处处可用。

示例 1:中文输出对比(避免"乱码/转义")

python 复制代码
# 标准库 json:默认 ensure_ascii=True,会输出 \uXXXX 转义
import json
data = {"msg": "你好,世界"}
print(json.dumps(data))
# 输出: {"msg": "\u4f60\u597d\uff0c\u4e16\u754c"}

# 正确直出 UTF-8(推荐)
print(json.dumps(data, ensure_ascii=False))
# 输出: {"msg": "你好,世界"}

# orjson:始终输出 UTF-8 bytes,不会转义为 ASCII
import orjson
print(orjson.dumps(data))
# 输出: b'{"msg":"你好,世界"}'
print(orjson.dumps(data).decode("utf-8"))
# 输出: {"msg": "你好,世界"}

要点:

  • Web 框架(如 FastAPI/Starlette)若使用 ORJSONResponse,会直接写 bytes,浏览器看到的就是 UTF-8。
  • 若走标准 JSONResponse,用 json.dumps(..., ensure_ascii=False) 也可确保中文直出。

示例 2:datetime 与 numpy 的零样板序列化

python 复制代码
import datetime as dt
import numpy as np
import orjson

obj = {
    "ts": dt.datetime(1970, 1, 1),
    "arr": np.array([[1, 2], [3, 4]]),
}

# 时区与 numpy 处理通过选项开启
payload = orjson.dumps(
    obj,
    option=orjson.OPT_NAIVE_UTC | orjson.OPT_SERIALIZE_NUMPY,
)
print(payload)
# b'{"ts":"1970-01-01T00:00:00+00:00","arr":[[1,2],[3,4]]}'

若用标准库 json,上述对象需要手工把 datetime 转字符串、把 ndarray 转 list。


示例 3:FastAPI 集成

python 复制代码
# pip install fastapi uvicorn orjson
from fastapi import FastAPI
from fastapi.responses import ORJSONResponse, JSONResponse

app = FastAPI()

@app.get("/orjson", response_class=ORJSONResponse)
async def use_orjson():
    return {"msg": "你好,世界", "nums": [1, 2, 3]}

@app.get("/json", response_class=JSONResponse)
async def use_json():
    # 若返回中文,建议 ensure_ascii=False(可由 JSONResponse 控制或自定义)
    return {"msg": "你好,世界", "nums": [1, 2, 3]}

# 也可以全局:FastAPI(default_response_class=ORJSONResponse)

提示:使用 ORJSONResponse 需要安装 orjson,否则会出现类似 "orjson must be installed to use ORJSONResponse" 的断言错误。


示例 4:微基准(仅作方向性参考)

python 复制代码
import time, json, orjson
m = {"a": 1, "b": [1, 2, 3], "msg": "你好"}

def bench(name, dumps, loads, loops=300_000):
    t0 = time.time()
    for _ in range(loops):
        s = dumps(m)
        loads(s)
    print(name, time.time() - t0)

bench("json", json.dumps, json.loads)
bench("orjson", lambda x: orjson.dumps(x), orjson.loads)

# 在多篇社区对比中,orjson 通常显著快于 json(机器/数据不同,结果会有差异)。

适用场景建议

  • 选 orjson:

    • 性能关键:高 QPS、低延迟接口;大型 JSON 读写;频繁序列化复杂对象
    • 类型友好 :项目中大量使用 dataclass、datetime、numpy、UUID 等
    • 一致编码:严格 UTF-8/RFC 8259 要求
  • 选 json:

    • 零依赖与可移植性:对环境极简、对部署体积敏感
    • 团队熟悉度:通用 API、学习成本低
    • PyPy/特殊运行时:orjson 不支持的场景

迁移与最佳实践

  1. 明确 bytes 与 str 的差异:orjson 的 dumps 返回 bytes;框架若可直接写 bytes,则无需再解码。

  2. 中文/多语言输出:

    • orjson 默认 UTF-8,无需额外参数;
    • 标准库要 ensure_ascii=False 才能直出 UTF-8。
  3. Pretty/排序:

    • json:indent 任意、sort_keys=True;
    • orjson:OPT_INDENT_2、OPT_SORT_KEYS。
  4. 字典非字符串键:

    • orjson 需 OPT_NON_STR_KEYS;注意潜在"重复键"风险(不同类型序列化后变为相同字符串)。
  5. 日期时间:

    • orjson 若需将 naive datetime 视为 UTC,使用 OPT_NAIVE_UTC;
    • 若需自定义输出,可用 OPT_PASSTHROUGH_DATETIME + default。
  6. 大整数/精度:

    • orjson 默认 64 位,或用 OPT_STRICT_INTEGER 限制 53 位;
    • 标准库虽更宽松,但传至 JS/DB 时仍需关注精度丢失。

参考

  • orjson 官方文档与 README(功能/选项/性能说明)
  • 基准文章(举例,方向性参考,结果随机器/数据不同而变)
相关推荐
DM今天肝到几点?1 天前
OpenAI 向全量用户开放 GPT-6 与 Intelligent UI:聊天框正在变成工作台
gpt·ui·chatgpt
空堂与归1 天前
清华VPP2登顶RoboDojo:凭预测解耦突围GPT-6
人工智能·gpt·ai·具身智能
空堂与归1 天前
GPT-6 智能界面上线,对话式 Agent 真没戏了?
人工智能·gpt·ai
AI日报派送佬1 天前
2026年10月8日AI行业日报|GPT-6可视化UI全面上线、AI PC硬件革新、智能体安全与商业化提速
人工智能·gpt·openai·谷歌·deepseek·ai日报·智能体技术
胖头鱼的鱼缸(尹海文)1 天前
胖头鱼的技术专栏-474 从能跑到能上线:PG SplitJSON 0.2.0 和 0.1.0 差在哪(20261008)
postgresql·json
进击的雷神2 天前
把 Claude/GPT 接进飞书、Telegram、Discord:一条命令跑起来的 OpenClaw 部署工具
gpt·飞书·openclaw
?? Daisy2 天前
Claude Code 接入 GPT:settings.json 两种配置方法(2026-10)
gpt·json
卡卡罗特学AI2 天前
从 Dots 到 GPT-6,OpenAI 想让你怎样使用 AI?
人工智能·gpt
小静AI工程实验室2 天前
Python 爬虫解析 JSON-LD:多块 script、@graph 与坏数据的 9 个边界
爬虫·python·json