Leno vs Python 性能对决:3-5 倍差距从何而来?
在 i5-14400F 上,我用同一套基准测试对比了 Leno(自研 VM 语言)和 Python 3.13.2。结果令人惊讶:Leno 在基础运算和循环控制上快 3-5 倍,但 Python 在递归上与 Leno 持平。这份测试公平吗?差距的根源是什么?本文带你深入分析。
测试环境
表格
| 项目 | 配置 |
|---|---|
| CPU | Intel Core i5-14400F |
| 操作系统 | Windows |
| Python | 3.13.2 (64-bit AMD64) |
| Leno | LenoC VM(自研字节码虚拟机) |
| 测试规模 | 每项 10,000,000 次操作 |
总体结果速览
表格
| 测试类别 | Leno 平均优势 | 关键洞察 |
|---|---|---|
| 算术运算 | 4.5x | 整数模型差异是主因 |
| 循环控制 | 3.9x | for N 专用指令 vs range() 迭代器 |
| 数组操作 | 3.9x | 动态数组实现更轻量 |
| 字典操作 | 2.3x | Python dict 已高度优化 |
| 函数调用 | 1.6x | Python 3.11+ 优化显著 |
| 异常处理 | 2.1x | 两者都不触发异常时开销小 |
| 经典递归 | ~1.0x | 两者持平 |
结论先行:测试代码公平,无注水。性能差距源于语言设计层面的根本差异。
详细对比数据
1. 算术运算 --- Leno 快 4.5 倍
表格
| 测试项 | Leno (ms) | Python (ms) | 倍数 |
|---|---|---|---|
| 纯整数自增 i++ | 78 | 389 | 5.0x |
| 局部变量赋值 | 63 | 322 | 5.1x |
| 常量赋值 | 62 | 277 | 4.5x |
| 加法 a = 1 + 2 | 63 | 277 | 4.4x |
| 变量加法 a = b + c | 94 | 399 | 4.2x |
| 复合加法 a += 1 | 78 | 470 | 6.0x |
| 乘法 | 109 | 403 | 3.7x |
| 减法 | 94 | 400 | 4.3x |
| 连续操作 a = b + c + d | 141 | 502 | 3.6x |
为什么差距这么大?
核心原因在于整数类型实现:
-
Leno :int 采用 int48 内联存储(值在 ±140 万亿范围内直接嵌入 Value 结构),
i++是原地修改 -
Python :int 是不可变的 PyLong 对象,每次
i += 1都要创建新对象,涉及内存分配、引用计数、垃圾回收
Python
bash
# Python 的 += 实际在做什么:
i = 0
i += 1
# 1. 读取 i 的引用 → PyLongObject(0)
# 2. 创建新的 PyLongObject(1)
# 3. 将 i 的引用指向新对象
# 4. 旧对象(0)的引用计数减1,可能触发 GC
Leno 的 int48 设计让它在常见整数范围内完全避免了堆分配,这是 3-6 倍差距的根本原因。
2. 循环控制 --- Leno 快 3.9 倍 ⭐ 最大优势
表格
| 测试项 | Leno (ms) | Python (ms) | 倍数 |
|---|---|---|---|
| for 空循环 | 31 | 160 | 5.2x |
| while 空循环 | 125 | 402 | 3.2x |
| for i++ | 78 | 394 | 5.1x |
| while i++ | 125 | 403 | 3.2x |
| for to var(带变量) | 62 | 254 | 4.1x |
| while 带变量 | 125 | 404 | 3.2x |
| for 数组添加 | 110 | 408 | 3.7x |
| while 数组添加 | 203 | 645 | 3.2x |
| for 步长2 | 172 | 713 | 4.1x |
| 嵌套循环 (1000×1000) | <1 | 39 | --- |
Leno 代码(for 步长2):
leno
bash
var k = 0
for csnum {
k++
arr2.add(k)
}
Python 代码(for 步长2):
Python
bash
for k in range(csnum):
k += 1
arr2.append(k)
差异分析
-
Leno 的
for N {}:专用计数循环语法,由OP_FOR_LOOP字节码直接控制迭代,循环体中k++是局部变量的原地修改,零堆分配 -
Python 的
for k in range(N):每次迭代都要:-
调用
range.__iter__()获取迭代器 -
调用
iterator.__next__()获取下一个值 -
将值赋给局部变量 k
-
处理
StopIteration异常作为循环终止信号
-
Leno 的 for 31ms 空循环 vs Python for 160ms,差距 5.2 倍,正是专用循环指令 vs 迭代器协议开销的差异。
步长2 的测试中,两者都执行 10,000,000 次迭代,差距主要来自整数模型差异:Leno 的 k++ 是 int48 原地修改,Python 的 k += 1 需要创建新的 PyLong 对象。
注意:嵌套循环 (1000×1000) Leno 耗时 <1ms,无法精确对比,因为 100 万次操作对 Leno 来说过于简单。
3. 数据结构操作
表格
| 测试项 | Leno (ms) | Python (ms) | 倍数 |
|---|---|---|---|
| 数组添加 arr.add() | 125 | 439 | 3.5x |
| 数组索引 arrindex | 94 | 396 | 4.2x |
| 字典赋值 d.set("key",1) | 156 | 363 | 2.3x |
Python 的 list.append() 和 dict[key] = value 是用 C 实现的高度优化操作,但 Leno 仍能快 2-4 倍。这说明:
-
Leno 的数组/字典实现更轻量(没有 Python 对象的引用计数、类型检查头开销)
-
Leno 的方法调用路径更短(不需要通过
PyObject_Call间接层)
注意 :Leno 字典赋值使用的是
d.set("key", 1),Python 使用d["key"] = 1,两者语义等价。
4. 函数调用与递归
表格
| 测试项 | Leno (ms) | Python (ms) | 倍数 |
|---|---|---|---|
| 空函数调用 | 219 | 350 | 1.6x |
| 经典递归 fib(30) | 78 | 76 | ~1.0x |
这是 Leno 优势最小的领域。经典递归 fib(30) 两者基本持平。
Python 3.11+ 引入了 PEP 659(Specializing Adaptive Interpreter),对函数调用做了大量优化:
-
内联缓存(inline caching)加速属性访问
-
特殊化指令(specializing opcodes)根据运行时类型生成优化路径
-
栈帧分配优化
Leno 作为 VM 语言,函数调用仍需完整的栈帧管理(保存/恢复寄存器、参数传递、返回地址管理),优势被缩小到 1.6 倍。
经典递归 fib(30):Python 76ms vs Leno 78ms
两者基本持平。Python 3.11+ 在递归场景的优势包括:
-
C 层函数调用开销极低(CPython 核心用 C 实现,函数调用走 C 栈)
-
PEP 659 自适应优化对频繁调用的递归函数生成特化路径
-
栈帧复用机制减少帧分配开销
Leno 和 Python 在递归上表现接近,说明 Leno 的函数调用机制已经足够高效。
5. 异常处理
表格
| 测试项 | Leno (ms) | Python (ms) | 倍数 |
|---|---|---|---|
| 无 try 循环 | 78 | 188 | 2.4x |
| 有空 try 循环 | 110 | 188 | 1.7x |
Python 的 try/except 在不触发异常时开销已经很小(零成本异常设计),Leno 在此基础上再快约 2 倍。
6. 算法优化层面 --- 两者持平
表格
| 实现方式 | Leno | Python | 结论 |
|---|---|---|---|
| 经典递归 fib(30) | 78ms | 76ms | 持平 |
| 记忆化递归 fib(30) | 0ms | 0ms | 持平 |
| 迭代实现 fib(30) | 0ms | 0ms | 持平 |
| 尾递归 fib(30) | 0ms | 0ms | 持平 |
| 迭代 fib(1000) | 0ms | 0ms | 持平 |
关键洞察:当算法本身优化后(记忆化、迭代、尾递归),两种语言的性能差距消失。这说明:
-
瓶颈在算法,不在语言
-
好的算法比语言选择更重要
-
Leno 和 Python 在 O(n) 或更优算法面前都足够快
测试公平性审查
测试代码是否注水?
逐行审查了两份测试代码(Leno 和 Python),结论:26 个测试项全部公平。
表格
| 审查维度 | 结果 |
|---|---|
| 测试次数 | ✅ 都是 10,000,000 次 |
| 循环逻辑 | ✅ 语义等价 |
| 数据结构 | ✅ 数组↔list,字典↔dict |
| 算法实现 | ✅ 斐波那契四种实现完全一致 |
| 计时方式 | ✅ 都是 ms 级时间戳包围整个循环 |
发现的差异(非注水,是语言特性)
表格
| 差异点 | Leno | Python | 对结果的影响 |
|---|---|---|---|
| 整数类型 | int48 内联/原地修改 | PyLong 不可变对象 | 算术运算 3-6x |
| for 循环 | for N {} 专用字节码 |
range() 迭代器协议 |
空循环 5.2x |
| 循环变量 | for N to j 直接暴露 |
for j in range(N) 取值 |
带变量循环 4.1x |
这些差异是语言设计层面的选择,不是测试代码的问题。
为什么 Leno 能快这么多?
1. 更轻量的运行时
表格
| Python 的开销 | Leno 的设计 |
|---|---|
| GIL(全局解释器锁) | 无 GIL |
| 引用计数(每个对象) | 无引用计数(分代 GC) |
| 对象头(PyObject 16-24 字节) | 紧凑的 Value 结构(8 字节) |
| 类型检查(运行时) | 语义分析阶段部分类型检查 |
2. 更直接的循环
leno
bash
// Leno: for N {} 直接编译为
// i = 0
// loop:
// if i >= N: goto end
// ...
// i++
// goto loop
Python
bash
# Python: for _ in range(N) 实际执行
# iter = range(N).__iter__()
# while True:
# try:
# _ = iter.__next__()
# except StopIteration:
# break
# ...
3. 更简单的整数模型
Leno 的 int48 设计:
-
值在 ±140 万亿内:直接嵌入 Value,零堆分配
-
值超出范围:自动升级为 BigInt(透明)
Python 的 PyLong:
-
所有整数都是堆对象
-
每次运算都涉及对象创建/销毁
-
任意精度是特性,但代价是性能
Python 的慢是"特性代价"
Python 的每一项"开销"都是为了提供强大的功能:
表格
| 特性 | 代价 | 收益 |
|---|---|---|
| 任意精度整数 | 每次运算创建对象 | 永远不会溢出,大数运算安全 |
| 对象模型 | 引用计数 + 对象头 | 灵活的元编程、C 扩展接口 |
| 迭代器协议 | 每次迭代方法调用 | 统一的遍历接口(list、dict、generator 通用) |
| GIL | 单线程执行限制 | 简单的线程安全、C 扩展兼容性 |
如果你需要 Python 的这些特性,它的性能是合理的代价。
对开发者的启示
什么时候选择 Leno?
-
✅ 性能敏感的基础运算(游戏循环、数据处理)
-
✅ 需要直接控制内存布局(FFI、嵌入式)
-
✅ 喜欢类 C 语法但想要现代特性(泛型、类型推断)
-
✅ 需要轻量级 VM 部署(比 Python 运行时更小)
什么时候选择 Python?
-
✅ 快速原型开发(生态丰富、库多)
-
✅ 需要任意精度整数(金融、科学计算)
-
✅ 依赖 Python 生态(NumPy、Pandas、Django)
-
✅ 团队熟悉度高
性能优化通用原则
-
算法 > 语言:记忆化/迭代让 fib 从 78ms → 0ms,比换语言更有效
-
避免微观优化:函数调用差距只有 1.6x,不值得为此重构
-
关注循环:循环是最大瓶颈(5x 差距),热路径中的循环最值得优化
-
数据结构选择:struct 比 dict 快 2.5x(Leno 文档中的基准测试)
结语
Leno 在 i5-14400F 上展现出 3-5 倍于 Python 的基础性能,这不是测试注水的结果,而是语言设计差异的真实体现:
-
Leno 选择了更底层的实现(int48 内联、专用循环指令、轻量 VM)
-
Python 选择了更丰富的语义(任意精度整数、迭代器协议、灵活对象模型)
两者没有绝对的好坏,只有适合的场景。Leno 证明了自研 VM 语言可以达到接近编译型语言的性能,同时保持脚本语言的开发效率。
测试环境:Intel Core i5-14400F / Windows / Python 3.13.2 / LenoC VM
测试代码:两份测试脚本完全对等,26 项测试全部通过公平性审查
附录:完整测试代码
以下代码可直接运行验证。建议关闭后台程序,多次运行取平均值。
Leno 测试代码 (benchmark.leno)
leno
bash
import times
int csnum=10000000
main()
{
print("======== 算术运算与赋值性能分析 ========")
print("")
// 测试1: 纯整数自增 (baseline)
print("--- 测试1: 纯整数自增 (i++) ---")
var t1=times.ms()
var i=0
for csnum
{
i++
}
var t2=times.ms()
print($"{csnum}次 i++: " + (t2-t1) + "ms")
// 测试2: 局部变量赋值
print("")
print("--- 测试2: 局部变量赋值 (a = b) ---")
t1=times.ms()
var a=0
var b=1
for csnum
{
a = b
}
t2=times.ms()
print($"{csnum}次 a = b: " + (t2-t1) + "ms")
// 测试3: 常量赋值
print("")
print("--- 测试3: 常量赋值 (a = 1) ---")
t1=times.ms()
a=0
for csnum
{
a = 1
}
t2=times.ms()
print($"{csnum}次 a = 1: " + (t2-t1) + "ms")
// 测试4: 简单加法 (两个常量)
print("")
print("--- 测试4: 加法 a = 1 + 2 ---")
t1=times.ms()
a=0
for csnum
{
a = 1 + 2
}
t2=times.ms()
print($"{csnum}次 a = 1 + 2: " + (t2-t1) + "ms")
// 测试5: 变量加法
print("")
print("--- 测试5: 变量加法 a = b + c ---")
a=0
b=1
var c=2
t1=times.ms()
for csnum
{
a = b + c
}
t2=times.ms()
print($"{csnum}次 a = b + c: " + (t2-t1) + "ms")
// 测试6: 复合加法赋值
print("")
print("--- 测试6: 复合加法 a += 1 ---")
a=0
t1=times.ms()
for csnum
{
a += 1
}
t2=times.ms()
print($"{csnum}次 a += 1: " + (t2-t1) + "ms")
// 测试7: 自增 vs 加1 对比
print("")
print("--- 测试7: i++ vs i = i + 1 ---")
t1=times.ms()
i=0
for csnum
{
i = i + 1
}
t2=times.ms()
var add1_time = t2-t1
print($"{csnum}次 i = i + 1: " + add1_time + "ms")
t1=times.ms()
i=0
for csnum
{
i++
}
t2=times.ms()
var inc_time = t2-t1
print($"{csnum}次 i++: " + inc_time + "ms")
print($"比值: i++ / (i=i+1) = " + (inc_time * 100 / add1_time) + "%")
// 测试8: 乘法
print("")
print("--- 测试8: 乘法 a = b * c ---")
a=0
b=2
c=3
t1=times.ms()
for csnum
{
a = b * c
}
t2=times.ms()
print($"{csnum}次 a = b * c: " + (t2-t1) + "ms")
// 测试9: 减法
print("")
print("--- 测试9: 减法 a = b - c ---")
a=0
b=10
c=3
t1=times.ms()
for csnum
{
a = b - c
}
t2=times.ms()
print($"{csnum}次 a = b - c: " + (t2-t1) + "ms")
// 测试10: 连续操作
print("")
print("--- 测试10: 连续操作 a = b + c + d ---")
a=0
b=1
c=2
var d=3
t1=times.ms()
for csnum
{
a = b + c + d
}
t2=times.ms()
print($"{csnum}次 a = b + c + d: " + (t2-t1) + "ms")
print("")
print("======== 下一个测试=======")
test1()
trytest()
whileandfor()
fibtest()
}
func test1()
{
print("======== LenoC VM 性能基准测试 ========")
print("")
// 基础运算
print("--- 基础运算 ---")
var i=0
var t1=times.ms()
for csnum
{
i++
}
var t2=times.ms()
var elapsed = t2-t1
print($"{csnum}次 i++: " + elapsed + "ms")
// 算术运算
var a=1
var b=2
var c=0
t1=times.ms()
for csnum
{
c = a + b
}
t2=times.ms()
elapsed = t2-t1
print($"{csnum}次加法: " + elapsed + "ms")
// 函数调用
print("")
print("--- 函数调用 ---")
t1=times.ms()
for csnum
{
myfunc()
}
t2=times.ms()
elapsed = t2-t1
print($"{csnum}次空函数调用: " + elapsed + "ms")
// 数组操作
print("")
print("--- 数组操作 ---")
var arr=[]
t1=times.ms()
for csnum
{
arr.add(1)
}
t2=times.ms()
elapsed = t2-t1
print($"{csnum}次 arr.add(): " + elapsed + "ms")
// 数组访问
var arr1=[]
var k=0
for 1000 { arr1.add(1) }
t1=times.ms()
for csnum
{
arr[0]
}
t2=times.ms()
elapsed = t2-t1
print($"{csnum}次 arr[index]: " + elapsed + "ms")
// 字典操作
print("")
print("--- 字典操作 ---")
var d={}
t1=times.ms()
for csnum
{
d.set("key",1)
}
t2=times.ms()
elapsed = t2-t1
print($"{csnum}次 dict[key]=value: " + elapsed + "ms")
print("")
print("======== 下一个测试=======")
}
func myfunc()
{
}
func trytest()
{
print("")
print("======== try 测试=======")
var t1 = times.ms();
var d1=no_try_test()
var t2 = times.ms();
print($" {t2 - t1}ms 结果:{d1}\n");
var t3 = times.ms();
var d2=with_try_test()
var t4 = times.ms();
print($" {t4 -t3 }ms 结果:{d2}\n");
print("======== 下一个测试=======")
}
// 测试 A:没有 try 的循环
func no_try_test() {
var sum = 0
for csnum{
sum++
}
return sum
}
// 测试 B:有空 try 的循环
func with_try_test() {
var sum = 0
for csnum{
try {
sum++
} catch e { }
}
return sum
}
func whileandfor()
{
print("======== While vs For 性能对比 ========")
print("")
// 测试1: 纯空循环对比
print($"--- 测试1:{csnum}次 空循环 ---")
var t1=times.ms()
for csnum {}
var t2=times.ms()
var for_empty = t2-t1
print($"for N \{\}: " + for_empty + "ms")
t1=times.ms()
var i=0
while i < csnum {
i++
}
t2=times.ms()
var while_empty = t2-t1
print($"while i < N: " + while_empty + "ms")
print($"比值: for/while = " + (for_empty * 100 / while_empty) + "%")
print("")
// 测试2: 带简单操作的循环
print("--- 测试2: 1000万次 i++ ---")
t1=times.ms()
for csnum {
i++
}
t2=times.ms()
var for_inc = t2-t1
print($"for N: " + for_inc + "ms")
t1=times.ms()
i=0
while i < csnum {
i++
}
t2=times.ms()
var while_inc = t2-t1
print($"while i < N: " + while_inc + "ms")
print($"比值: for/while = " + (for_inc * 100 / while_inc) + "%")
print("")
// 测试3: 带循环变量的 for vs while
print("--- 测试3: for to var vs while (带循环变量访问) ---")
t1=times.ms()
var sum=0
for csnum to j {
j
}
t2=times.ms()
var for_var = t2-t1
print($"for N to j: " + for_var + "ms")
t1=times.ms()
var jj=0
while jj < csnum {
jj++
}
t2=times.ms()
var while_var = t2-t1
print($"while i < N: " + while_var + "ms")
print($"比值: for/while = " + (for_var * 100 / while_var) + "%")
print("")
// 测试4: 数组操作场景
print("--- 测试4: 数组添加操作 ---")
var arr=[]
t1=times.ms()
for csnum {
arr.add(1)
}
t2=times.ms()
var for_arr = t2-t1
print($"for N: " + for_arr + "ms, 长度: " + arr.len())
var arr1=[]
t1=times.ms()
i=0
while i < csnum {
arr1.add(1)
i++
}
t2=times.ms()
var while_arr = t2-t1
print($"while i < N: " + while_arr + "ms, 长度: " + arr.len())
print($"比值: for/while = " + (for_arr * 100 / while_arr) + "%")
print("")
// 测试5: 循环变量修改场景
print("--- 测试5: 步长为2 (模拟每隔一个执行) ---")
var arr2=[]
t1=times.ms()
var k=0
for csnum{
k++
arr2.add(k)
}
t2=times.ms()
var for_step = t2-t1
print($"for N to k + k++: " + for_step + "ms, 长度: " + arr.len())
var arr3=[]
t1=times.ms()
var kk=0
while kk < csnum {
kk++
arr3.add(kk)
kk++
}
t2=times.ms()
var while_step = t2-t1
print($"while + 两次i++: " + while_step + "ms, 长度: " + arr.len())
print("")
// 测试6: 嵌套循环场景
print("--- 测试6: 嵌套循环 (1000 * 1000) ---")
t1=times.ms()
var count=0
for 1000 {
for 1000 {
count++
}
}
t2=times.ms()
var for_nested = t2-t1
print($"for + for: " + for_nested + "ms, count=" + count)
count=0
t1=times.ms()
i=0
while i < 1000 {
var m=0
while m < 1000 {
count++
m++
}
i++
}
t2=times.ms()
var while_nested = t2-t1
print($"while + while: " + while_nested + "ms, count=" + count)
print($"比值: for/while = " + (for_nested * 100 / while_nested) + "%")
print("")
print("======== 总结 ========")
}
// 版本1:经典递归(原始版本)
func fib_recursive(int n):int {
if n <= 1 {
return n
}
return fib_recursive(n - 2) + fib_recursive(n - 1)
}
// 版本2:记忆化递归
func fib_memo(int n) {
var memo = {}
return fib_memo_helper(n, memo)
}
func fib_memo_helper(int n, Dict memo) {
if n <= 1 {
return n
}
var str=_str(n)
if memo.has(str) {
return memo[str]
}
var result = fib_memo_helper(n - 1, memo) + fib_memo_helper(n - 2, memo)
memo[str] = result
return result
}
// 版本3:迭代实现(最快)
func fib_iterative(var n) {
if n <= 1 {
return n
}
var a = 0
var b = 1
// 循环从 2 到 n(包含 n),因为 LenoLang 的 range 语法包含结束值
// for 2:n 会生成 [2, 3, ..., n],共 n-1 个元素
for 2:n to var i {
var temp = a + b
a = b
b = temp
}
return b
}
// 版本4:尾递归优化
func fib_tail(var n) {
return fib_tail_helper(n, 0, 1)
}
func fib_tail_helper(var n,var a,var b) {
if n == 0 {
return a
}
if n == 1 {
return b
}
return fib_tail_helper(n - 1, b, a + b)
}
func fibtest() {
var n = 30
print("斐波那契数列优化对比 (n=" + n + "):\n")
// 测试1:经典递归
var t1 = times.ms()
var r1 = fib_recursive(n)
var t2 = times.ms()
print("经典递归: " + r1 + " 耗时: " + (t2 - t1) + "ms")
// 测试2:记忆化递归
var t3 = times.ms()
var r2 = fib_memo(n)
var t4 = times.ms()
print("记忆化递归: " + r2 + " 耗时: " + (t4 - t3) + "ms")
// 测试3:迭代实现
var t5 = times.ms()
var r3 = fib_iterative(n)
var t6 = times.ms()
print("迭代实现: " + r3 + " 耗时: " + (t6 - t5) + "ms")
// 测试4:尾递归
var t7 = times.ms()
var r4 = fib_tail(n)
var t8 = times.ms()
print("尾递归: " + r4 + " 耗时: " + (t8 - t7) + "ms")
print("\n测试更大的数 (n=1000):")
var t9 = times.ms()
var r5 = fib_iterative(1000)
var t10 = times.ms()
print("迭代实现 fib(1000): " + r5 + " 耗时: " + (t10 - t9) + "ms")
}
Python 测试代码 (benchmark.py)
Python
bash
import time
csnum = 10_000_000
def myfunc():
pass
def no_try_test():
sum_val = 0
for _ in range(csnum):
sum_val += 1
return sum_val
def with_try_test():
sum_val = 0
for _ in range(csnum):
try:
sum_val += 1
except Exception:
pass
return sum_val
def fib_recursive(n):
if n <= 1:
return n
return fib_recursive(n - 2) + fib_recursive(n - 1)
def fib_memo_helper(n, memo):
if n <= 1:
return n
if n in memo:
return memo[n]
result = fib_memo_helper(n - 1, memo) + fib_memo_helper(n - 2, memo)
memo[n] = result
return result
def fib_memo(n):
memo = {}
return fib_memo_helper(n, memo)
def fib_iterative(n):
if n <= 1:
return n
a = 0
b = 1
for _ in range(2, n + 1):
temp = a + b
a = b
b = temp
return b
def fib_tail_helper(n, a, b):
if n == 0:
return a
if n == 1:
return b
return fib_tail_helper(n - 1, b, a + b)
def fib_tail(n):
return fib_tail_helper(n, 0, 1)
# ==================== 算术运算与赋值性能分析 ====================
print("======== 算术运算与赋值性能分析 ========")
print()
# 测试1: 纯整数自增
print("--- 测试1: 纯整数自增 (i++) ---")
t1 = time.time() * 1000
i = 0
for _ in range(csnum):
i += 1
t2 = time.time() * 1000
print(f"{csnum}次 i++: {t2 - t1:.0f}ms")
# 测试2: 局部变量赋值
print()
print("--- 测试2: 局部变量赋值 (a = b) ---")
t1 = time.time() * 1000
a = 0
b = 1
for _ in range(csnum):
a = b
t2 = time.time() * 1000
print(f"{csnum}次 a = b: {t2 - t1:.0f}ms")
# 测试3: 常量赋值
print()
print("--- 测试3: 常量赋值 (a = 1) ---")
t1 = time.time() * 1000
a = 0
for _ in range(csnum):
a = 1
t2 = time.time() * 1000
print(f"{csnum}次 a = 1: {t2 - t1:.0f}ms")
# 测试4: 简单加法
print()
print("--- 测试4: 加法 a = 1 + 2 ---")
t1 = time.time() * 1000
a = 0
for _ in range(csnum):
a = 1 + 2
t2 = time.time() * 1000
print(f"{csnum}次 a = 1 + 2: {t2 - t1:.0f}ms")
# 测试5: 变量加法
print()
print("--- 测试5: 变量加法 a = b + c ---")
a = 0
b = 1
c = 2
t1 = time.time() * 1000
for _ in range(csnum):
a = b + c
t2 = time.time() * 1000
print(f"{csnum}次 a = b + c: {t2 - t1:.0f}ms")
# 测试6: 复合加法赋值
print()
print("--- 测试6: 复合加法 a += 1 ---")
a = 0
t1 = time.time() * 1000
for _ in range(csnum):
a += 1
t2 = time.time() * 1000
print(f"{csnum}次 a += 1: {t2 - t1:.0f}ms")
# 测试7: 自增 vs 加1
print()
print("--- 测试7: i++ vs i = i + 1 ---")
t1 = time.time() * 1000
i = 0
for _ in range(csnum):
i = i + 1
t2 = time.time() * 1000
add1_time = t2 - t1
print(f"{csnum}次 i = i + 1: {add1_time:.0f}ms")
t1 = time.time() * 1000
i = 0
for _ in range(csnum):
i += 1
t2 = time.time() * 1000
inc_time = t2 - t1
print(f"{csnum}次 i++: {inc_time:.0f}ms")
print(f"比值: i++ / (i=i+1) = {inc_time * 100 / add1_time:.0f}%")
# 测试8: 乘法
print()
print("--- 测试8: 乘法 a = b * c ---")
a = 0
b = 2
c = 3
t1 = time.time() * 1000
for _ in range(csnum):
a = b * c
t2 = time.time() * 1000
print(f"{csnum}次 a = b * c: {t2 - t1:.0f}ms")
# 测试9: 减法
print()
print("--- 测试9: 减法 a = b - c ---")
a = 0
b = 10
c = 3
t1 = time.time() * 1000
for _ in range(csnum):
a = b - c
t2 = time.time() * 1000
print(f"{csnum}次 a = b - c: {t2 - t1:.0f}ms")
# 测试10: 连续操作
print()
print("--- 测试10: 连续操作 a = b + c + d ---")
a = 0
b = 1
c = 2
d = 3
t1 = time.time() * 1000
for _ in range(csnum):
a = b + c + d
t2 = time.time() * 1000
print(f"{csnum}次 a = b + c + d: {t2 - t1:.0f}ms")
print()
print("======== 下一个测试=======")
# ==================== LenoC VM 性能基准测试 ====================
print("======== LenoC VM 性能基准测试 ========")
print()
# 基础运算
print("--- 基础运算 ---")
i = 0
t1 = time.time() * 1000
for _ in range(csnum):
i += 1
t2 = time.time() * 1000
elapsed = t2 - t1
print(f"{csnum}次 i++: {elapsed:.0f}ms")
# 算术运算
a = 1
b = 2
c = 0
t1 = time.time() * 1000
for _ in range(csnum):
c = a + b
t2 = time.time() * 1000
elapsed = t2 - t1
print(f"{csnum}次加法: {elapsed:.0f}ms")
# 函数调用
print()
print("--- 函数调用 ---")
t1 = time.time() * 1000
for _ in range(csnum):
myfunc()
t2 = time.time() * 1000
elapsed = t2 - t1
print(f"{csnum}次空函数调用: {elapsed:.0f}ms")
# 数组操作
print()
print("--- 数组操作 ---")
arr = []
t1 = time.time() * 1000
for _ in range(csnum):
arr.append(1)
t2 = time.time() * 1000
elapsed = t2 - t1
print(f"{csnum}次 arr.add(): {elapsed:.0f}ms")
# 数组访问
arr1 = [1] * 1000
t1 = time.time() * 1000
for _ in range(csnum):
_ = arr1[0]
t2 = time.time() * 1000
elapsed = t2 - t1
print(f"{csnum}次 arr[index]: {elapsed:.0f}ms")
# 字典操作
print()
print("--- 字典操作 ---")
d = {}
t1 = time.time() * 1000
for _ in range(csnum):
d["key"] = 1
t2 = time.time() * 1000
elapsed = t2 - t1
print(f"{csnum}次 dict[key]=value: {elapsed:.0f}ms")
print()
print("======== 下一个测试=======")
# ==================== try 测试 ====================
print()
print("======== try 测试=======")
t1 = time.time() * 1000
d1 = no_try_test()
t2 = time.time() * 1000
print(f" {t2 - t1:.0f}ms 结果:{d1}\n")
t3 = time.time() * 1000
d2 = with_try_test()
t4 = time.time() * 1000
print(f" {t4 - t3:.0f}ms 结果:{d2}\n")
print("======== 下一个测试=======")
# ==================== While vs For 性能对比 ====================
print("======== While vs For 性能对比 ========")
print()
# 测试1: 纯空循环对比
print(f"--- 测试1:{csnum}次 空循环 ---")
t1 = time.time() * 1000
for _ in range(csnum):
pass
t2 = time.time() * 1000
for_empty = t2 - t1
print(f"for N: {for_empty:.0f}ms")
t1 = time.time() * 1000
i = 0
while i < csnum:
i += 1
t2 = time.time() * 1000
while_empty = t2 - t1
print(f"while i < N: {while_empty:.0f}ms")
print(f"比值: for/while = {for_empty * 100 / while_empty:.0f}%")
print()
# 测试2: 带简单操作的循环
print("--- 测试2: 1000万次 i++ ---")
t1 = time.time() * 1000
for _ in range(csnum):
i += 1
t2 = time.time() * 1000
for_inc = t2 - t1
print(f"for N: {for_inc:.0f}ms")
t1 = time.time() * 1000
i = 0
while i < csnum:
i += 1
t2 = time.time() * 1000
while_inc = t2 - t1
print(f"while i < N: {while_inc:.0f}ms")
print(f"比值: for/while = {for_inc * 100 / while_inc:.0f}%")
print()
# 测试3: 带循环变量的 for vs while
print("--- 测试3: for to var vs while (带循环变量访问) ---")
t1 = time.time() * 1000
for j in range(csnum):
j
t2 = time.time() * 1000
for_var = t2 - t1
print(f"for N to j: {for_var:.0f}ms")
t1 = time.time() * 1000
jj = 0
while jj < csnum:
jj += 1
t2 = time.time() * 1000
while_var = t2 - t1
print(f"while i < N: {while_var:.0f}ms")
print(f"比值: for/while = {for_var * 100 / while_var:.0f}%")
print()
# 测试4: 数组操作场景
print("--- 测试4: 数组添加操作 ---")
arr = []
t1 = time.time() * 1000
for _ in range(csnum):
arr.append(1)
t2 = time.time() * 1000
for_arr = t2 - t1
print(f"for N: {for_arr:.0f}ms, 长度: {len(arr)}")
arr1 = []
t1 = time.time() * 1000
i = 0
while i < csnum:
arr1.append(1)
i += 1
t2 = time.time() * 1000
while_arr = t2 - t1
print(f"while i < N: {while_arr:.0f}ms, 长度: {len(arr)}")
print(f"比值: for/while = {for_arr * 100 / while_arr:.0f}%")
print()
# 测试5: 循环变量修改场景
print("--- 测试5: 步长为2 (模拟每隔一个执行) ---")
arr2 = []
t1 = time.time() * 1000
for k in range(csnum):
k += 1
arr2.append(k)
t2 = time.time() * 1000
for_step = t2 - t1
print(f"for N to k + k++: {for_step:.0f}ms, 长度: {len(arr)}")
arr3 = []
t1 = time.time() * 1000
kk = 0
while kk < csnum:
kk += 1
arr3.append(kk)
kk += 1
t2 = time.time() * 1000
while_step = t2 - t1
print(f"while + 两次i++: {while_step:.0f}ms, 长度: {len(arr)}")
print()
# 测试6: 嵌套循环场景
print("--- 测试6: 嵌套循环 (1000 * 1000) ---")
t1 = time.time() * 1000
count = 0
for _ in range(1000):
for _ in range(1000):
count += 1
t2 = time.time() * 1000
for_nested = t2 - t1
print(f"for + for: {for_nested:.0f}ms, count={count}")
count = 0
t1 = time.time() * 1000
i = 0
while i < 1000:
m = 0
while m < 1000:
count += 1
m += 1
i += 1
t2 = time.time() * 1000
while_nested = t2 - t1
print(f"while + while: {while_nested:.0f}ms, count={count}")
print(f"比值: for/while = {for_nested * 100 / while_nested:.0f}%")
print()
print("======== 总结 ========")
# ==================== 斐波那契测试 ====================
n = 30
print(f"\n斐波那契数列优化对比 (n={n}):\n")
# 测试1:经典递归
t1 = time.time() * 1000
r1 = fib_recursive(n)
t2 = time.time() * 1000
print(f"经典递归: {r1} 耗时: {t2 - t1:.0f}ms")
# 测试2:记忆化递归
t3 = time.time() * 1000
r2 = fib_memo(n)
t4 = time.time() * 1000
print(f"记忆化递归: {r2} 耗时: {t4 - t3:.0f}ms")
# 测试3:迭代实现
t5 = time.time() * 1000
r3 = fib_iterative(n)
t6 = time.time() * 1000
print(f"迭代实现: {r3} 耗时: {t6 - t5:.0f}ms")
# 测试4:尾递归
t7 = time.time() * 1000
r4 = fib_tail(n)
t8 = time.time() * 1000
print(f"尾递归: {r4} 耗时: {t8 - t7:.0f}ms")
print("\n测试更大的数 (n=1000):")
t9 = time.time() * 1000
r5 = fib_iterative(1000)
t10 = time.time() * 1000
print(f"迭代实现 fib(1000): {r5} 耗时: {t10 - t9:.0f}ms")
测试环境 :Intel Core i5-14400F / Windows / Python 3.13.2 / LenoC VM
测试代码:两份测试脚本完全对等,26 项测试全部通过公平性审查