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(功能/选项/性能说明)
  • 基准文章(举例,方向性参考,结果随机器/数据不同而变)
相关推荐
API流转日记14 小时前
对接gemini-2.5-flash-image-preview教程
人工智能·gpt·ai·chatgpt·ai作画
一个很老的小萌新19 小时前
json 解析 [{“id“:1,“name“:“apple“},{“id“:2,“name“:“banana“}]
java·前端·json
花生糖@1 天前
GPT-5发布:统一智能体时代的开启——从“工具”到“协作者”的范式跃迁
gpt·ai·gpt5
中國龍在廣州2 天前
GPT-5冷酷操盘,游戏狼人杀一战封神!七大LLM狂飙演技,人类玩家看完沉默
人工智能·gpt·深度学习·机器学习·计算机视觉·机器人
seegaler2 天前
AMD显卡运行GPT-OSS全攻略
gpt·ai·amd·gpt-oss
Hello123网站2 天前
孟子GPT
gpt·ai工具
微笑伴你而行2 天前
目标检测如何将同时有方形框和旋转框的json/xml标注转为txt格式
xml·目标检测·json
cdcdhj2 天前
数据库存储大量的json文件怎么样高效的读取和分页,利用文件缓存办法不占用内存
缓存·node.js·json
陈敬雷-充电了么-CEO兼CTO2 天前
具身智能多模态感知与场景理解:融合语言模型的多模态大模型
人工智能·python·gpt·语言模型·自然语言处理·chatgpt·多模态
Z_z在努力2 天前
【杂类】JSON:现代Web开发的数据交换基石
json