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