结论先行
同一个 a = a + 1 循环跑 10⁸ 次,同机、shm 后端,隔离测量「每操作一次 KV 往返」的地板成本:
| 实现 |
用时 |
iters/s |
ns/iter |
vs Rust |
vs Python |
Rust(rustc -O,black_box 防优化) |
0.257 s |
389.6 M |
2.57 |
1× |
— |
Python 3(原生 while) |
8.052 s |
12.4 M |
80.5 |
31.4× |
1× |
| kvspace-c(get+decode / encode+set,shm 直连) |
69.58 s |
1.44 M |
695.8 |
271× |
8.6× |
度量方法
- Rust:
while black_box(a) < black_box(n) { a = black_box(a)+1 },std::hint::black_box 逐次包裹阻止循环被折叠/消除;Instant 计时。rustc -O。
- Python:
a=0; while a < n: a = a+1,time.perf_counter_ns()。
- kvspace-c:连
shm://,循环 kvspaceGet("a") → kvspaceDecodeHead → 读 int64 body → +1 → kvspaceNewInt64 → kvspaceSet("a"),CLOCK_MONOTONIC 计时。链 /usr/lib/libkvspace.so(前端 shm dispatch),二进制 gcc -O2。逐迭代等价于 kvlang 的 a=a+1(一次 get + 一次 set)。
- 三版均
N=100000000,末值校验 a==100000000。脚本:/tmp/iopsbench/{loop.rs,loop.py,kv.c}。
原始数据(ns/iter):Rust 2.567;Python 80.519;kvspace-c 695.8(总 69.583 s)。
分析
- Rust→Python 的 31× 是「原生寄存器/栈」对「字节码解释 + 对象装箱」的代价。
- Python→kvspace-c 的 8.6× 是「进程内变量」变成「持久 KV 项」的代价——即便 KV 层本身已是 shm 内存态、纯 C、无网络,单次 get/set 仍要一趟 ABI + 一次
art_search + 一次 TLV 编解码。
- kvlang 当前把每一个操作数(局部
a/n、临时 rem/divisible)都当作可跨 vthread 寻址、可软链接、可崩溃恢复的 KV 项来读写——等价于 CPython 把每个 LOAD_FAST 都换成对持久化字典的 get/set。这条微基准给出该设计的单操作成本下界。
关联
后续
读写码改进方案(参考 CPython fast-locals / 值栈 / PEP 659,引入 local/stack/kv 操作数分层 + 检查点写回)见下方评论。
结论先行
同一个
a = a + 1循环跑 10⁸ 次,同机、shm 后端,隔离测量「每操作一次 KV 往返」的地板成本:rustc -O,black_box防优化)while)‥pc落盘、前端 DSN dispatch、帧路径拼接、三维地址解码。真实 kvlang 的一次a=a+1还要叠加这些,故prime_sieve(2-runtime/prime_sieve bench:解释执行每操作 KV 往返 → 计算密集慢 Python ~138,500×(关联 #116 寻址开销) #194)才是几十 µs/op 量级。本微基准把 2-runtime/prime_sieve bench:解释执行每操作 KV 往返 → 计算密集慢 Python ~138,500×(关联 #116 寻址开销) #194 定位的「每操作一次 KV 往返」这一正交成本单独钉死。度量方法
while black_box(a) < black_box(n) { a = black_box(a)+1 },std::hint::black_box逐次包裹阻止循环被折叠/消除;Instant计时。rustc -O。a=0; while a < n: a = a+1,time.perf_counter_ns()。shm://,循环kvspaceGet("a") → kvspaceDecodeHead → 读 int64 body → +1 → kvspaceNewInt64 → kvspaceSet("a"),CLOCK_MONOTONIC计时。链/usr/lib/libkvspace.so(前端 shm dispatch),二进制gcc -O2。逐迭代等价于 kvlang 的a=a+1(一次 get + 一次 set)。N=100000000,末值校验a==100000000。脚本:/tmp/iopsbench/{loop.rs,loop.py,kv.c}。原始数据(ns/iter):Rust
2.567;Python80.519;kvspace-c695.8(总69.583 s)。分析
art_search+ 一次 TLV 编解码。a/n、临时rem/divisible)都当作可跨 vthread 寻址、可软链接、可崩溃恢复的 KV 项来读写——等价于 CPython 把每个LOAD_FAST都换成对持久化字典的 get/set。这条微基准给出该设计的单操作成本下界。关联
prime_sieve端到端 bench(27.3 s,三维地址版),定位「每操作一次 KV 往返 × 往返次数」。本 issue 单独量化「单次往返」这一因子。[irseq,params]减小单次往返的 key 体积(33.37 s→27.3 s,~18%),但不改变往返次数与单次 KV 地板价——本 issue 的 695.8 ns 与 key 形态正交。后续
读写码改进方案(参考 CPython fast-locals / 值栈 / PEP 659,引入
local/stack/kv操作数分层 + 检查点写回)见下方评论。