feat: 添加性能基准测试脚本 — 12类18项覆盖算术/函数/闭包/数组/对象/字符串/算法
This commit is contained in:
@@ -0,0 +1,524 @@
|
||||
// ============================================================================
|
||||
// Aster 性能基准测试
|
||||
// 运行: cargo run -- examples/benchmark.ast
|
||||
// 目的: 用于树遍历解释器 vs VM 的性能对比
|
||||
//
|
||||
// 注: debug 模式下总耗时约 30-60s,release 模式会快 10-50x
|
||||
// ============================================================================
|
||||
|
||||
// --- 高阶工具函数 (被后续 benchmark 使用) ---
|
||||
|
||||
fn map(arr, func) {
|
||||
let result = []
|
||||
for (x in arr) {
|
||||
push(result, func(x))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fn filter(arr, pred) {
|
||||
let result = []
|
||||
for (x in arr) {
|
||||
if (pred(x)) {
|
||||
push(result, x)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fn reduce(arr, func, init) {
|
||||
let acc = init
|
||||
for (x in arr) {
|
||||
acc = func(acc, x)
|
||||
}
|
||||
return acc
|
||||
}
|
||||
|
||||
fn sort(arr) {
|
||||
let n = len(arr)
|
||||
let i = 0
|
||||
while (i < n - 1) {
|
||||
let j = 0
|
||||
while (j < n - i - 1) {
|
||||
if (arr[j] > arr[j + 1]) {
|
||||
let tmp = arr[j]
|
||||
arr[j] = arr[j + 1]
|
||||
arr[j + 1] = tmp
|
||||
}
|
||||
j = j + 1
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// --- 基准测试框架 ---
|
||||
|
||||
fn bench(name, thunk) {
|
||||
let t0 = clock()
|
||||
let result = thunk()
|
||||
let t1 = clock()
|
||||
let elapsed = t1 - t0
|
||||
print(name + ": " + result + " \ttime=" + elapsed + "s")
|
||||
return result
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 1. 算术运算压测 — 测试基本运算 + 循环调度开销
|
||||
// ============================================================================
|
||||
|
||||
print("=== 1. Arithmetic ===")
|
||||
|
||||
bench("1a. int loop 1M", fn() {
|
||||
let sum = 0
|
||||
let i = 0
|
||||
while (i < 1000000) {
|
||||
sum = sum + i
|
||||
i = i + 1
|
||||
}
|
||||
return sum
|
||||
})
|
||||
|
||||
bench("1b. FP mul 500K", fn() {
|
||||
let x = 1.0
|
||||
let i = 0
|
||||
while (i < 500000) {
|
||||
x = x * 1.00001
|
||||
i = i + 1
|
||||
}
|
||||
return x
|
||||
})
|
||||
|
||||
bench("1c. compound assign 1M", fn() {
|
||||
let a = 0
|
||||
let i = 0
|
||||
while (i < 1000000) {
|
||||
a += i
|
||||
i += 1
|
||||
}
|
||||
return a
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// 2. 函数调用开销 — 测试各种调用模式
|
||||
// ============================================================================
|
||||
|
||||
print("")
|
||||
print("=== 2. Function Calls ===")
|
||||
|
||||
fn empty() { return 42 }
|
||||
|
||||
bench("2a. call empty fn 200K", fn() {
|
||||
let i = 0
|
||||
while (i < 200000) {
|
||||
empty()
|
||||
i = i + 1
|
||||
}
|
||||
return empty()
|
||||
})
|
||||
|
||||
fn add(a, b) { return a + b }
|
||||
|
||||
bench("2b. call add(a,b) 200K", fn() {
|
||||
let s = 0
|
||||
let i = 0
|
||||
while (i < 200000) {
|
||||
s = add(s, i)
|
||||
i = i + 1
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
fn fact(n) {
|
||||
if (n <= 1) { return 1 }
|
||||
return n * fact(n - 1)
|
||||
}
|
||||
|
||||
bench("2c. recursion fact(10) 10K", fn() {
|
||||
let i = 0
|
||||
while (i < 10000) {
|
||||
fact(10)
|
||||
i = i + 1
|
||||
}
|
||||
return fact(10)
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// 3. 闭包压测 — 闭包创建与调用
|
||||
// ============================================================================
|
||||
|
||||
print("")
|
||||
print("=== 3. Closures ===")
|
||||
|
||||
fn make_mult(k) {
|
||||
return fn(x) { return x * k }
|
||||
}
|
||||
|
||||
bench("3a. create + call closure 100K", fn() {
|
||||
let m = make_mult(7)
|
||||
let s = 0
|
||||
let i = 0
|
||||
while (i < 100000) {
|
||||
s = s + m(i)
|
||||
i = i + 1
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
bench("3b. inline lambda map 10K", fn() {
|
||||
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
let i = 0
|
||||
let s = 0
|
||||
while (i < 10000) {
|
||||
let doubled = map(arr, fn(x) { return x * 2 })
|
||||
s = s + doubled[0]
|
||||
i = i + 1
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// 4. 数组操作
|
||||
// ============================================================================
|
||||
|
||||
print("")
|
||||
print("=== 4. Array ===")
|
||||
|
||||
bench("4a. array index get 1M", fn() {
|
||||
let arr = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
|
||||
let s = 0
|
||||
let i = 0
|
||||
while (i < 1000000) {
|
||||
s = s + arr[i % 10]
|
||||
i = i + 1
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
bench("4b. array index set 500K", fn() {
|
||||
let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
let i = 0
|
||||
while (i < 500000) {
|
||||
arr[i % 10] = i
|
||||
i = i + 1
|
||||
}
|
||||
return arr[0] + arr[9]
|
||||
})
|
||||
|
||||
bench("4c. push + pop 100K", fn() {
|
||||
let arr = []
|
||||
let i = 0
|
||||
while (i < 100000) {
|
||||
push(arr, i)
|
||||
i = i + 1
|
||||
}
|
||||
while (len(arr) > 0) {
|
||||
pop(arr)
|
||||
}
|
||||
return len(arr)
|
||||
})
|
||||
|
||||
bench("4d. for-in array 10K items", fn() {
|
||||
let arr = []
|
||||
let i = 0
|
||||
while (i < 10000) {
|
||||
push(arr, i)
|
||||
i = i + 1
|
||||
}
|
||||
let s = 0
|
||||
for (x in arr) {
|
||||
s = s + x
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// 5. 对象操作
|
||||
// ============================================================================
|
||||
|
||||
print("")
|
||||
print("=== 5. Object ===")
|
||||
|
||||
bench("5a. object field read 200K", fn() {
|
||||
let obj = { a: 1, b: 2, c: 3, d: 4, e: 5 }
|
||||
let s = 0
|
||||
let i = 0
|
||||
while (i < 200000) {
|
||||
s = s + obj.a + obj.b + obj.c
|
||||
i = i + 1
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
bench("5b. object field write 200K", fn() {
|
||||
let obj = { x: 0, y: 0 }
|
||||
let i = 0
|
||||
while (i < 200000) {
|
||||
obj.x = i
|
||||
obj.y = obj.x + 1
|
||||
i = i + 1
|
||||
}
|
||||
return obj.x + obj.y
|
||||
})
|
||||
|
||||
bench("5c. object bracket get 200K", fn() {
|
||||
let obj = { name: "test", age: 25 }
|
||||
let s = ""
|
||||
let i = 0
|
||||
while (i < 200000) {
|
||||
s = obj["name"]
|
||||
i = i + 1
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// 6. 字符串操作
|
||||
// ============================================================================
|
||||
|
||||
print("")
|
||||
print("=== 6. String ===")
|
||||
|
||||
bench("6a. string concat 50K", fn() {
|
||||
let s = ""
|
||||
let i = 0
|
||||
while (i < 50000) {
|
||||
s = s + "a"
|
||||
i = i + 1
|
||||
}
|
||||
return len(s)
|
||||
})
|
||||
|
||||
bench("6b. split + join pattern 10K", fn() {
|
||||
let csv = "alice,bob,carol,dave,eve"
|
||||
let i = 0
|
||||
let c = 0
|
||||
while (i < 10000) {
|
||||
let parts = split(csv, ",")
|
||||
c = c + len(parts)
|
||||
i = i + 1
|
||||
}
|
||||
return c
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// 7. 高阶函数链 — map/filter/reduce
|
||||
// ============================================================================
|
||||
|
||||
print("")
|
||||
print("=== 7. Higher-order ===")
|
||||
|
||||
bench("7a. map+filter+reduce chain 1000", fn() {
|
||||
let data = []
|
||||
let i = 0
|
||||
while (i < 100) {
|
||||
push(data, i)
|
||||
i = i + 1
|
||||
}
|
||||
let n = 0
|
||||
while (n < 1000) {
|
||||
let r = reduce(
|
||||
map(
|
||||
filter(data, fn(x) { return x % 2 == 0 }),
|
||||
fn(x) { return x * x }
|
||||
),
|
||||
fn(a, b) { return a + b },
|
||||
0
|
||||
)
|
||||
n = n + 1
|
||||
}
|
||||
return n
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// 8. 复杂算法 — 冒泡排序
|
||||
// ============================================================================
|
||||
|
||||
print("")
|
||||
print("=== 8. Algorithms ===")
|
||||
|
||||
bench("8a. bubble sort 100 items x 50", fn() {
|
||||
let template = [42, 17, 8, 99, 3, 56, 23, 91, 5, 67,
|
||||
34, 12, 78, 1, 55, 88, 19, 73, 44, 28,
|
||||
66, 37, 81, 14, 50, 95, 7, 63, 29, 41,
|
||||
85, 21, 52, 9, 76, 33, 68, 15, 47, 92,
|
||||
25, 58, 4, 71, 39, 83, 11, 54, 97, 30,
|
||||
64, 18, 49, 2, 87, 36, 74, 22, 59, 45,
|
||||
90, 6, 53, 27, 80, 13, 48, 94, 31, 69,
|
||||
16, 57, 43, 89, 24, 61, 8, 75, 38, 46,
|
||||
100, 20, 65, 10, 79, 35, 72, 26, 82, 51,
|
||||
98, 32, 77, 40, 84, 62, 93, 3, 70, 70]
|
||||
let i = 0
|
||||
while (i < 50) {
|
||||
let arr = []
|
||||
let j = 0
|
||||
while (j < 100) {
|
||||
push(arr, template[j])
|
||||
j = j + 1
|
||||
}
|
||||
sort(arr)
|
||||
i = i + 1
|
||||
}
|
||||
return i
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// 9. 斐波那契 — 递归 vs 迭代对比
|
||||
// ============================================================================
|
||||
|
||||
print("")
|
||||
print("=== 9. Fibonacci ===")
|
||||
|
||||
fn fib_rec(n) {
|
||||
if (n <= 1) { return n }
|
||||
return fib_rec(n - 1) + fib_rec(n - 2)
|
||||
}
|
||||
|
||||
bench("9a. fib_rec(25) x 10", fn() {
|
||||
let i = 0
|
||||
let r = 0
|
||||
while (i < 10) {
|
||||
r = fib_rec(25)
|
||||
i = i + 1
|
||||
}
|
||||
return r
|
||||
})
|
||||
|
||||
fn fib_iter(n) {
|
||||
if (n <= 1) { return n }
|
||||
let a = 0
|
||||
let b = 1
|
||||
let i = 2
|
||||
while (i <= n) {
|
||||
let tmp = a + b
|
||||
a = b
|
||||
b = tmp
|
||||
i = i + 1
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
bench("9b. fib_iter(100) x 10K", fn() {
|
||||
let i = 0
|
||||
while (i < 10000) {
|
||||
fib_iter(100)
|
||||
i = i + 1
|
||||
}
|
||||
return fib_iter(100)
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// 10. 变量访问 — 全局 vs 局部 vs 深层闭包
|
||||
// ============================================================================
|
||||
|
||||
print("")
|
||||
print("=== 10. Variable Access ===")
|
||||
|
||||
let g = 100
|
||||
|
||||
fn use_global() {
|
||||
return g + 1
|
||||
}
|
||||
|
||||
bench("10a. global var read 200K", fn() {
|
||||
let i = 0
|
||||
let s = 0
|
||||
while (i < 200000) {
|
||||
s = s + g
|
||||
i = i + 1
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
bench("10b. local var read 200K", fn() {
|
||||
let local = 100
|
||||
let i = 0
|
||||
let s = 0
|
||||
while (i < 200000) {
|
||||
s = s + local
|
||||
i = i + 1
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
fn deep_scope() {
|
||||
let a = 1
|
||||
let b = 2
|
||||
let c = 3
|
||||
let d = 4
|
||||
let e = 5
|
||||
return fn() {
|
||||
return fn() {
|
||||
return fn() {
|
||||
return a + b + c + d + e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bench("10c. nested closure call 100K", fn() {
|
||||
let get = deep_scope()()()
|
||||
let i = 0
|
||||
let s = 0
|
||||
while (i < 100000) {
|
||||
s = s + get()
|
||||
i = i + 1
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// 11. 分支判断
|
||||
// ============================================================================
|
||||
|
||||
print("")
|
||||
print("=== 11. Conditionals ===")
|
||||
|
||||
bench("11a. if-else chain 500K", fn() {
|
||||
let s = 0
|
||||
let i = 0
|
||||
while (i < 500000) {
|
||||
if (i % 3 == 0) {
|
||||
s = s + 1
|
||||
} else if (i % 3 == 1) {
|
||||
s = s + 2
|
||||
} else {
|
||||
s = s + 3
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// 12. 综合混合负载
|
||||
// ============================================================================
|
||||
|
||||
print("")
|
||||
print("=== 12. Mixed Workload ===")
|
||||
|
||||
bench("12a. mixed (arith+obj+array+call)", fn() {
|
||||
let s = 0
|
||||
let i = 0
|
||||
while (i < 50000) {
|
||||
s = s + i * 2 - i / 2 + i % 7
|
||||
|
||||
let pt = { x: i, y: i + 1, z: i + 2 }
|
||||
s = s + pt.x + pt.y - pt.z
|
||||
|
||||
let arr = [i, i + 1, i + 2, i + 3, i + 4]
|
||||
s = s + arr[0] + arr[i % 5]
|
||||
|
||||
s = s + add(pt.x, arr[1])
|
||||
|
||||
i = i + 1
|
||||
}
|
||||
return s
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// 13. 总结
|
||||
// ============================================================================
|
||||
|
||||
print("")
|
||||
print("=== Benchmark Complete ===")
|
||||
Reference in New Issue
Block a user