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 &lt; csnum {
i++
}
t2=times.ms()
var while_empty = t2-t1
print($"while i &lt; 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 &lt; csnum {
i++
}
t2=times.ms()
var while_inc = t2-t1
print($"while i &lt; 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 &lt; csnum {
jj++
}
t2=times.ms()
var while_var = t2-t1
print($"while i &lt; 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 &lt; csnum {
arr1.add(1)
i++
}
t2=times.ms()
var while_arr = t2-t1
print($"while i &lt; 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 &lt; 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 &lt; 1000 {
var m=0
while m &lt; 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 语言的最新版本,查看源代码,并运行本文中的基准测试代码进行验证。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐