263 lines
5.6 KiB
Plaintext
263 lines
5.6 KiB
Plaintext
// micro_ops.bench.ce (or .cm depending on your convention)
|
|
|
|
// Note: We use a function-local sink in each benchmark to avoid cross-contamination
|
|
function blackhole(sink, x) {
|
|
// Prevent dead-code elimination
|
|
return (sink + (x | 0)) | 0
|
|
}
|
|
|
|
function make_obj_xy(x, y) {
|
|
return { x, y }
|
|
}
|
|
|
|
function make_obj_yx(x, y) {
|
|
// Different insertion order to force a different shape in many engines
|
|
return { y, x }
|
|
}
|
|
|
|
function make_shapes(n) {
|
|
var out = []
|
|
for (var i = 0; i < n; i++) {
|
|
var o = { a: i }
|
|
o[`p${i}`] = i
|
|
push(out, o)
|
|
}
|
|
return out
|
|
}
|
|
|
|
function make_packed_array(n) {
|
|
var a = []
|
|
for (var i = 0; i < n; i++) push(a, i)
|
|
return a
|
|
}
|
|
|
|
function make_holey_array(n) {
|
|
var a = []
|
|
for (var i = 0; i < n; i += 2) a[i] = i
|
|
return a
|
|
}
|
|
|
|
return {
|
|
// 0) Baseline loop cost
|
|
loop_empty: function(n) {
|
|
var sink = 0
|
|
for (var i = 0; i < n; i++) {}
|
|
return blackhole(sink, n)
|
|
},
|
|
|
|
// 1) Numeric pipelines
|
|
i32_add: function(n) {
|
|
var sink = 0
|
|
var x = 1
|
|
for (var i = 0; i < n; i++) x = (x + 3) | 0
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
f64_add: function(n) {
|
|
var sink = 0
|
|
var x = 1.0
|
|
for (var i = 0; i < n; i++) x = x + 3.14159
|
|
return blackhole(sink, x | 0)
|
|
},
|
|
|
|
mixed_add: function(n) {
|
|
var sink = 0
|
|
var x = 1
|
|
for (var i = 0; i < n; i++) x = x + 0.25
|
|
return blackhole(sink, x | 0)
|
|
},
|
|
|
|
bit_ops: function(n) {
|
|
var sink = 0
|
|
var x = 0x12345678
|
|
for (var i = 0; i < n; i++) x = ((x << 5) ^ (x >>> 3)) | 0
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
overflow_path: function(n) {
|
|
var sink = 0
|
|
var x = 0x70000000
|
|
for (var i = 0; i < n; i++) x = (x + 0x10000000) | 0
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
// 2) Branching
|
|
branch_predictable: function(n) {
|
|
var sink = 0
|
|
var x = 0
|
|
for (var i = 0; i < n; i++) {
|
|
if ((i & 7) != 0) x++
|
|
else x += 2
|
|
}
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
branch_alternating: function(n) {
|
|
var sink = 0
|
|
var x = 0
|
|
for (var i = 0; i < n; i++) {
|
|
if ((i & 1) == 0) x++
|
|
else x += 2
|
|
}
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
// 3) Calls
|
|
call_direct: function(n) {
|
|
var sink = 0
|
|
function f(a) { return (a + 1) | 0 }
|
|
var x = 0
|
|
for (var i = 0; i < n; i++) x = f(x)
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
call_indirect: function(n) {
|
|
var sink = 0
|
|
function f(a) { return (a + 1) | 0 }
|
|
var g = f
|
|
var x = 0
|
|
for (var i = 0; i < n; i++) x = g(x)
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
call_closure: function(n) {
|
|
var sink = 0
|
|
function make_adder(k) {
|
|
return function(a) { return (a + k) | 0 }
|
|
}
|
|
var add3 = make_adder(3)
|
|
var x = 0
|
|
for (var i = 0; i < n; i++) x = add3(x)
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
// 4) Object props (ICs / shapes)
|
|
prop_read_mono: function(n) {
|
|
var sink = 0
|
|
var o = make_obj_xy(1, 2)
|
|
var x = 0
|
|
for (var i = 0; i < n; i++) x = (x + o.x) | 0
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
prop_read_poly_2: function(n) {
|
|
var sink = 0
|
|
var a = make_obj_xy(1, 2)
|
|
var b = make_obj_yx(1, 2)
|
|
var x = 0
|
|
for (var i = 0; i < n; i++) {
|
|
var o = (i & 1) == 0 ? a : b
|
|
x = (x + o.x) | 0
|
|
}
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
prop_read_mega: function(n) {
|
|
var sink = 0
|
|
var objs = make_shapes(32)
|
|
var x = 0
|
|
for (var i = 0; i < n; i++) {
|
|
var o = objs[i & 31]
|
|
x = (x + o.a) | 0
|
|
}
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
prop_write_mono: function(n) {
|
|
var sink = 0
|
|
var o = make_obj_xy(1, 2)
|
|
for (var i = 0; i < n; i++) o.x = (o.x + 1) | 0
|
|
return blackhole(sink, o.x)
|
|
},
|
|
|
|
// 5) Arrays
|
|
array_read_packed: function(n) {
|
|
var sink = 0
|
|
var a = make_packed_array(1024)
|
|
var x = 0
|
|
for (var i = 0; i < n; i++) x = (x + a[i & 1023]) | 0
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
array_write_packed: function(n) {
|
|
var sink = 0
|
|
var a = make_packed_array(1024)
|
|
for (var i = 0; i < n; i++) a[i & 1023] = i
|
|
return blackhole(sink, a[17] | 0)
|
|
},
|
|
|
|
array_read_holey: function(n) {
|
|
var sink = 0
|
|
var a = make_holey_array(2048)
|
|
var x = 0
|
|
for (var i = 0; i < n; i++) {
|
|
var v = a[(i & 2047)]
|
|
// If "missing" is a special value in your language, this stresses that path too
|
|
if (v) x = (x + v) | 0
|
|
}
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
array_push_steady: function(n) {
|
|
var sink = 0
|
|
var x = 0
|
|
for (var j = 0; j < n; j++) {
|
|
var a = []
|
|
for (var i = 0; i < 256; i++) push(a, i)
|
|
x = (x + length(a)) | 0
|
|
}
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
// 6) Strings
|
|
string_concat_small: function(n) {
|
|
var sink = 0
|
|
var x = 0
|
|
for (var j = 0; j < n; j++) {
|
|
var s = ""
|
|
for (var i = 0; i < 16; i++) s = s + "x"
|
|
x = (x + length(s)) | 0
|
|
}
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
// 7) Allocation / GC pressure
|
|
alloc_tiny_objects: function(n) {
|
|
var sink = 0
|
|
var x = 0
|
|
for (var i = 0; i < n; i++) {
|
|
var o = { a: i, b: i + 1, c: i + 2 }
|
|
x = (x + o.b) | 0
|
|
}
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
alloc_linked_list: function(n) {
|
|
var sink = 0
|
|
var head = null
|
|
for (var i = 0; i < n; i++) head = { v: i, next: head }
|
|
var x = 0
|
|
var p = head
|
|
while (p) {
|
|
x = (x + p.v) | 0
|
|
p = p.next
|
|
}
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
// 8) meme-specific (adapt these to your exact semantics)
|
|
meme_clone_read: function(n) {
|
|
// If meme(obj) clones like Object.create / prototypal clone, this hits it hard.
|
|
// Replace with your exact meme call form.
|
|
var sink = 0
|
|
var base = { x: 1, y: 2 }
|
|
var x = 0
|
|
for (var i = 0; i < n; i++) {
|
|
var o = meme(base)
|
|
x = (x + o.x) | 0
|
|
}
|
|
return blackhole(sink, x)
|
|
},
|
|
|
|
}
|