你以为 import json、datetime.now() 这些操作很安全?
其实,它们正悄悄拖垮你的程序。
今天就来扒一扒那些被我们当成“工具人”的标准库函数——
表面无害,实则暗藏性能陷阱。
json.loads():别再无脑用了!
json 是万能胶水?错!
它在解析大文本时,速度远不如 orjson 或 ujson。
import json, orjson, time
data = '{"user": "Alice", "id": 12345}' * 10000
start = time.time()
for _ in range(1000):
json.loads(data)
print("json:", time.time() - start) # ≈0.8s
start = time.time()
for _ in range(1000):
orjson.loads(data)
print("orjson:", time.time() - start) # ≈0.2s
快4倍不是玄学,是事实。
尤其在高并发 API 里,这点差距会被放大成雪崩。
datetime.now():时间获取也有坑?
你以为 datetime.now() 很轻量?
它默认会读取系统时区信息,涉及系统调用。
from datetime import datetime
import time
# 慢
start = time.perf_counter()
for _ in range(100000):
datetime.now()
print("with tz:", time.perf_counter() - start)
# 快
start = time.perf_counter()
for _ in range(100000):
datetime.utcnow()
print("utc:", time.perf_counter() - start)
实测快30%以上(Linux 环境)。
如果不需要时区,直接用 time.time() 更狠——纳秒级开销。
re.compile():别每次都在循环里编译!
正则表达式强大,但重复编译是性能自杀。
import re, time
text = "user123@example.com" * 1000
# 错误示范
start = time.time()
for _ in range(1000):
re.search(r'\w+@\w+\.\w+', text)
print("no compile:", time.time() - start)
# 正确姿势
pattern = re.compile(r'\w+@\w+\.\w+')
start = time.time()
for _ in range(1000):
pattern.search(text)
print("compiled:", time.time() - start)
差距可达5倍!
Python 的 re 模块虽缓存最近编译结果,但不稳定,别赌。
os.path.join() vs pathlib:新旧之争
老派写法:
import os
path = os.path.join("data", "logs", "app.log")
新派写法:
from pathlib import Path
path = Path("data") / "logs" / "app.log"
pathlib 更慢?不一定!
在大量路径拼接场景下,Path 对象可复用,避免字符串反复拼接。
但注意:**pathlib 创建对象有开销**。
若只是简单拼一次路径,os.path.join 反而更快。
别盲目追新,看场景。
collections.defaultdict:方便≠高效
想自动初始化字典?
from collections import defaultdict
d = defaultdict(list)
d['key'].append(1)
但默认工厂函数每次 miss 都要调用。
如果 key 极多且稀疏,开销不小。
对比普通 dict + .setdefault():
d = {}
d.setdefault('key', []).append(1)
在高频写入场景,后者快15%~20%(实测百万次操作)。
defaultdict 适合逻辑清晰、可读性优先的场景,非性能优先。
pickle:序列化的“甜蜜陷阱”
开发时图快,用 pickle 存模型、缓存数据?
小心反序列化变“反性能”。
import pickle, dill, time
obj = {"data": list(range(10000))}
# 序列化
pkl = pickle.dumps(obj)
start = time.time()
for _ in range(1000):
pickle.loads(pkl)
print("pickle load:", time.time() - start)
更糟的是,pickle 不跨语言、不安全、体积大。
考虑 msgpack 或 protobuf——体积小30%,速度翻倍,还安全。
写在最后:标准库不是“免死金牌”
Python 标准库稳定、可靠,但不等于高效。
很多函数为通用性牺牲了性能,比如:
str.replace() 在长字符串中多次调用 → 改用 str.translate()list.append() 在预知大小时 → 改用 [None] * n 预分配time.sleep(0.001) 精度不足 → 用 time.perf_counter() + 自旋(慎用)
真正的高手,既会用标准库,也敢绕过它。
性能优化不是炫技,而是对用户负责——
每一毫秒,都是体验。
下次写代码前,先问一句:
“这个标准库调用,真的没得选了吗?” 💡