Leno vs Python 性能对决:3-5 倍差距从何而来?
Leno vs Python 性能对决:3-5 倍差距从何而来?
在 i5-14400F 上,我用同一套基准测试对比了 Leno(自研 VM 语言)和 Python 3.13.2。结果令人惊讶:Leno 在基础运算和循环控制上快 3-5 倍,但 Python 在递归上与 Leno 持平。这份测试公平吗?差距的根源是什么?本文带你深入分析。
📥 提示:本文末尾附有完整的基准测试代码和 Leno 语言项目下载地址,方便读者验证和进一步探索。
测试环境
| 项目 | 配置 |
|---|---|
| CPU | Intel Core i5-14400F |
| 操作系统 | Windows |
| Python | 3.13.2 (64-bit AMD64) |
| Leno | LenoC VM(自研字节码虚拟机) |
| 测试规模 | 每项 10,000,000 次操作 |
总体结果速览
| 测试类别 | Leno 平均优势 | 关键洞察 |
|---|---|---|
| 算术运算 | 4.5x | 整数模型差异是主因 |
| 循环控制 | 4.0x | for N 专用指令 vs range() 迭代器 |
| 数组操作 | 3.5x | 动态数组实现更轻量 |
| 字典操作 | 3.3x | Python dict 已高度优化 |
| 函数调用 | 1.5x | Python 3.11+ 优化显著 |
| 异常处理 | 2.0x | 两者都不触发异常时开销小 |
| 经典递归 | ~1.0x | 两者持平(Python 略快) |
结论先行:测试代码公平,无注水。性能差距源于语言设计层面的根本差异。
详细对比数据
1. 算术运算 — Leno 快 4.5 倍
| 测试项 | Leno (ms) | Python (ms) | 倍数 |
|---|---|---|---|
| 纯整数自增 i++ | 78 | 474 | 6.1x |
| 局部变量赋值 | 78 | 354 | 4.5x |
| 常量赋值 | 62 | 280 | 4.5x |
| 加法 a = 1 + 2 | 78 | 273 | 3.5x |
| 变量加法 a = b + c | 110 | 461 | 4.2x |
| 复合加法 a += 1 | 78 | 417 | 5.3x |
| 乘法 | 110 | 454 | 4.1x |
| 减法 | 109 | 483 | 4.4x |
| 连续操作 a = b + c + d | 141 | 667 | 4.7x |
为什么差距这么大?
核心原因在于整数类型实现:
- Leno:int 采用 int48 内联存储(值在 ±140 万亿范围内直接嵌入 Value 结构),
i++是原地修改 - Python:int 是不可变的 PyLong 对象,每次
i += 1都要创建新对象,涉及内存分配、引用计数、垃圾回收
# 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 空循环 | 47 | 188 | 4.0x |
| while 空循环 | 109 | 520 | 4.8x |
| for i++ | 78 | 468 | 6.0x |
| while i++ | 125 | 502 | 4.0x |
| for to var(带变量) | 47 | 329 | 7.0x |
| while 带变量 | 125 | 410 | 3.3x |
| for 数组添加 | 110 | 410 | 3.7x |
| while 数组添加 | 203 | 658 | 3.2x |
| for 步长2 | 62 | 224 | 3.6x |
| while 步长2 | 125 | 537 | 4.3x |
| 嵌套循环 (1000×1000) | 16 | 42 | 2.6x |
Leno 代码(for 步长2 — 三段式步长语法 start:end:step):
for 0:csnum-1:2 to k {
arr2.add(k)
}
Python 代码(for 步长2 — range 自带步长参数):
for k in range(0, csnum, 2):
arr2.append(k)
Leno 代码(while 步长2 — 完全公平对比):
var kk = 0
while kk < csnum {
kk++
arr3.add(kk)
kk++
}
Python 代码(while 步长2 — 完全公平对比):
kk = 0
while kk < csnum:
kk += 1
arr3.append(kk)
kk += 1
差异分析
- Leno 的
for start:end:step to k {}:三段式数值循环语法,与 Python 的range(start, end, step)语义等价,步长由循环控制,体内无需额外操作,由OP_FOR_LOOP字节码直接驱动 - Python 的
range(0, N, 2):步长由range参数控制,体内同样不需要额外操作。但每次迭代仍有迭代器协议开销(__next__→StopIteration) - while 步长2:两边语义完全一致(体内两次
++),是纯粹公平的 VM vs CPython 对比
步长 2 的测试中,迭代次数减半(约 5,000,000 次),差距主要来自整数模型差异:Leno 的 k++ 是 int48 原地修改,Python 的 k += 1 需要创建新的 PyLong 对象。
注意:嵌套循环 (1000×1000) Leno 耗时约 16ms,Python 约 42ms,差距缩小到约 2.6x,因为 100 万次操作对两者都已较轻量。
3. 数据结构操作
| 测试项 | Leno (ms) | Python (ms) | 倍数 |
|---|---|---|---|
| 数组添加 arr.add() | 125 | 433 | 3.5x |
| 数组索引 arr[index] | 94 | 404 | 4.3x |
| 字典赋值 d.set("key",1) | 156 | 508 | 3.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) | 倍数 |
|---|---|---|---|
| 空函数调用 | 234 | 356 | 1.5x |
| 经典递归 fib(30) | 94 | 79 | 0.8x |
这是 Leno 优势最小的领域。经典递归 fib(30) 两者基本持平。
Python 3.11+ 引入了 PEP 659(Specializing Adaptive Interpreter),对函数调用做了大量优化:
- 内联缓存(inline caching)加速属性访问
- 特殊化指令(specializing opcodes)根据运行时类型生成优化路径
- 栈帧分配优化
Leno 作为 VM 语言,函数调用仍需完整的栈帧管理(保存/恢复寄存器、参数传递、返回地址管理),优势被缩小到 1.6 倍。
经典递归 fib(30):Python 79ms vs Leno 94ms
两者基本持平。Python 3.11+ 在递归场景的优势包括:
- C 层函数调用开销极低(CPython 核心用 C 实现,函数调用走 C 栈)
- PEP 659 自适应优化对频繁调用的递归函数生成特化路径
- 栈帧复用机制减少帧分配开销
Leno 和 Python 在递归上表现接近,说明 Leno 的函数调用机制已经足够高效。
5. 异常处理
| 测试项 | Leno (ms) | Python (ms) | 倍数 |
|---|---|---|---|
| 无 try 循环 | 79 | 184 | 2.3x |
| 有空 try 循环 | 109 | 182 | 1.7x |
Python 的 try/except 在不触发异常时开销已经很小(零成本异常设计),Leno 在此基础上再快约 2 倍。
6. 算法优化层面 — 两者持平
| 实现方式 | Leno | Python | 结论 |
|---|---|---|---|
| 经典递归 fib(30) | 94ms | 79ms | Python 略快 |
| 记忆化递归 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() 迭代器协议 |
空循环 4.0x |
| 循环变量 | for N to j 直接暴露 |
for j in range(N) 取值 |
带变量循环 7.0x |
这些差异是语言设计层面的选择,不是测试代码的问题。
为什么 Leno 能快这么多?
1. 更轻量的运行时
| Python 的开销 | Leno 的设计 |
|---|---|
| GIL(全局解释器锁) | 无 GIL |
| 引用计数(每个对象) | 无引用计数(分代 GC) |
| 对象头(PyObject 16-24 字节) | 紧凑的 Value 结构(8 字节) |
| 类型检查(运行时) | 语义分析阶段部分类型检查 |
2. 更直接的循环
// Leno: for N {} 直接编译为
// i = 0
// loop:
// if i >= N: goto end
// ...
// i++
// goto loop
# 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 语言可以达到接近编译型语言的性能,同时保持脚本语言的开发效率。
补充验证:同一套测试在 i5-3470、i3-8100T 等老机型上也跑过,Leno 的加速比规律完全一致(3~6 倍),结论不依赖于特定 CPU。
测试环境:Intel Core i5-14400F / Windows / Python 3.13.2 / LenoC VM
测试代码:两份测试脚本完全对等,26 项测试全部通过公平性审查
附录:完整测试代码
以下代码可直接运行验证。建议关闭后台程序,多次运行取平均值。
Leno 测试代码 (benchmark.leno)
leno
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: for 步长2 (各自最自然的写法) ---")
var arr2=[]
t1=times.ms()
for 0:csnum-1:2 to k {
arr2.add(k)
}
t2=times.ms()
var for_step = t2-t1
print($"for 0:csnum:2 to k: " + for_step + "ms, 长度: " + arr2.len())
print("")
// 测试5b: while 步长2 (完全公平对比)
print("--- 测试5b: while 步长2 (完全公平对比) ---")
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, 长度: " + arr3.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
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: for 步长为2 (range 自带步长参数,与 Leno for 0:csnum-1:2 to k 语义等价)
print("--- 测试5: for 步长为2 (range(0, csnum, 2)) ---")
arr2 = []
t1 = time.time() * 1000
for k in range(0, csnum, 2):
arr2.append(k)
t2 = time.time() * 1000
for_step = t2 - t1
print(f"for 步长2: {for_step:.0f}ms, 长度: {len(arr2)}")
测试5b: while 步长为2 (完全公平对比,体内两次自增)
print("--- 测试5b: while 步长为2 (两次i++) ---")
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 步长2: {while_step:.0f}ms, 长度: {len(arr3)}")
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 项测试全部通过公平性审查
项目地址
本文中测试的 Leno 语言项目地址:https://gitee.com/cheng8214/LenoLang/releases/tag/v0.1.1
GitHub - cheng8214/LenoLang: LenoLang — a scripting language born of passion. Not a Python replacement (weak ecosystem). Not a systems language like Rust/Go. Not a "best practices" textbook (evolved through trial and error). Faster than Python 3.13, with direct FFI pixel access, small enough for one person. I wrote it for fun. If Leno looks cool, check it out and share ideas! · GitHub
您可以在该地址下载 Leno 语言的最新版本,查看源代码,并运行本文中的基准测试代码进行验证。
更多推荐




所有评论(0)