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

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

结论先行

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

基本差异一览

  • 返回类型

    • jsonjson.dumps(obj) 返回 str
    • orjsonorjson.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.dataclassdatetime/date/timeuuid.UUIDnumpy.ndarray 等;也支持 enumTypedDict 等。
    • json :遇到上述对象通常需要自定义 default 处理或手动转换。
  • 字典键(非字符串)

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

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

    • jsonindent=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 读写;频繁序列化复杂对象
    • 类型友好 :项目中大量使用 dataclassdatetimenumpyUUID
    • 一致编码:严格 UTF-8/RFC 8259 要求
  • 选 json:

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

迁移与最佳实践

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

  2. 中文/多语言输出:

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

    • json:indent 任意、sort_keys=True
    • orjson:OPT_INDENT_2OPT_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(功能/选项/性能说明)
  • 基准文章(举例,方向性参考,结果随机器/数据不同而变)
相关推荐
万粉变现经纪人2 小时前
何解决PyCharm中pip install安装Python报错ModuleNotFoundError: No module named ‘json’问题
python·pycharm·json·beautifulsoup·scikit-learn·matplotlib·pip
量子位4 小时前
我们都错怪GPT-5了,路由统一算力,免费用户也能创造收益
gpt·ai编程
哪吒编程8 小时前
GPT-5发布引发用户强烈反弹,OpenAI紧急回应
gpt·chatgpt·openai
Leinwin11 小时前
微软发布GPT-5赋能的Copilot:重构办公场景的智能革命
gpt·microsoft·copilot
zhurui_xiaozhuzaizai13 小时前
OpenAI官方写的GPT-5 prompt指南
gpt·prompt
星际码仔1 天前
图解 GPT-5 提示词:这可能是全网最“直观”的《 GPT-5 提示词指南》拆解
gpt·ai编程
Pi_Qiu_1 天前
Python初学者笔记第二十二期 -- (JSON数据解析)
笔记·python·json
mon_star°1 天前
有趣的 npm 库 · json-server
前端·npm·json
不焦躁的程序员1 天前
选择gpt-5还是claude-4-sonnect
人工智能·gpt·cursor