lua ngx.time() 和 os.time() 性能对比
在 OpenResty 里,
实测差距 10–30 倍 甚至更高,且随着 QPS 上涨线性放大。
ngx.time() 是纯 C 实现、无系统调用、无锁、无 GC 的 毫秒级缓存值;os.time() 要走 libc → kernel → 返回,还涉及 Lua 栈转换和 GC 装箱。实测差距 10–30 倍 甚至更高,且随着 QPS 上涨线性放大。
- 实现差异
| 函数 | 来源 | 实现路径 | 精度 | 系统调用 | Lua GC 对象 | |---|---|---|---|---|---| |ngx.time()| ngx_http_lua_module | 直接读ngx_time_t *tp->sec(更新频率 1 ms) | 秒 | ❌ | ❌ | |os.time()| PUC-Rio Lua |luaB_time→time(2)→gettimeofday/clock_gettime| 秒 | ✅ | ✅(返回 number) |
- 基准数据
在一台 2.6 GHz Xeon 上,单 worker、空循环 1 000 万次:
lua
local ngx_now = ngx.timelocal t0 = ngx.now()for i = 1,1e7 do
local _ = ngx_now()endprint("ngx.time()", ngx.now()-t0) -- ≈ 0.08 st0 = ngx.now()for i = 1,1e7 do
local _ = os.time()endprint("os.time()", ngx.now()-t0) -- ≈ 1.1 s→ 13 倍差距;若把循环换成
resty.core 的 FFI 版本,差距可拉到 30 倍。- 业务真实场景
在 20 k RPS 的接口里,每次取 10 次时间戳(日志、缓存 key、超时计算):
| 方案 | CPU 占比 |
|---|---|
os.time() | 5.8 % |
ngx.time() | 0.18 % |
| → 直接省出 5.6 % 的单核 CPU,等价于每 18 个核省 1 个核。 |
- 何时仍用
os.time()
- 代码需要在 纯 Lua 环境(非 OpenResty)里也能跑;
- 需要 亚秒精度 且愿意承担
gettimeofday调用——这时应直接用ngx.now()(浮点毫秒)或ngx.time()+ngx.update_time()组合。
一句话
在 OpenResty 内部永远优先
在 OpenResty 内部永远优先
lua
local now = ngx.time()比
os.time() 快一个数量级,无系统调用、无 GC 压力,精度同样到秒。