218 lines
5.0 KiB
TypeScript
218 lines
5.0 KiB
TypeScript
// Direct micro-benchmarks for LuaTable operations.
|
|
// These bypass Lua eval to isolate LuaTable overhead.
|
|
|
|
import { bench } from "vitest";
|
|
import {
|
|
jsToLuaValue,
|
|
LuaStackFrame,
|
|
LuaTable,
|
|
luaValueToJS,
|
|
} from "../client/space_lua/runtime.ts";
|
|
|
|
const sf = LuaStackFrame.lostFrame;
|
|
|
|
// --- Construction ---
|
|
|
|
bench("LuaTable: construct empty", () => {
|
|
new LuaTable();
|
|
});
|
|
|
|
// --- jsToLuaValue conversion ---
|
|
|
|
const smallArray = Array.from({ length: 10 }, (_, i) => i);
|
|
const medArray = Array.from({ length: 100 }, (_, i) => i);
|
|
const largeArray = Array.from({ length: 1000 }, (_, i) => i);
|
|
|
|
bench("jsToLuaValue: array (10 elements)", () => {
|
|
jsToLuaValue(smallArray);
|
|
});
|
|
|
|
bench("jsToLuaValue: array (100 elements)", () => {
|
|
jsToLuaValue(medArray);
|
|
});
|
|
|
|
bench("jsToLuaValue: array (1000 elements)", () => {
|
|
jsToLuaValue(largeArray);
|
|
});
|
|
|
|
const smallObj: Record<string, any> = {};
|
|
for (let i = 0; i < 10; i++) smallObj[`k${i}`] = `v${i}`;
|
|
const medObj: Record<string, any> = {};
|
|
for (let i = 0; i < 100; i++) medObj[`k${i}`] = `v${i}`;
|
|
|
|
bench("jsToLuaValue: object (10 keys)", () => {
|
|
jsToLuaValue(smallObj);
|
|
});
|
|
|
|
bench("jsToLuaValue: object (100 keys)", () => {
|
|
jsToLuaValue(medObj);
|
|
});
|
|
|
|
// Nested structure (common: array of objects)
|
|
const nestedData = Array.from({ length: 100 }, (_, i) => ({
|
|
name: `item_${i}`,
|
|
value: i,
|
|
tags: ["a", "b"],
|
|
}));
|
|
|
|
bench("jsToLuaValue: nested array of objects (100)", () => {
|
|
jsToLuaValue(nestedData);
|
|
});
|
|
|
|
// --- String key set/get ---
|
|
|
|
bench("LuaTable: string key set+get (1k ops)", () => {
|
|
const t = new LuaTable();
|
|
for (let i = 0; i < 1000; i++) {
|
|
void t.set(`key_${i}`, i);
|
|
}
|
|
let sum = 0;
|
|
for (let i = 0; i < 1000; i++) {
|
|
sum += t.get(`key_${i}`) as number;
|
|
}
|
|
return sum;
|
|
});
|
|
|
|
bench("LuaTable: string key rawSet+rawGet (1k ops)", () => {
|
|
const t = new LuaTable();
|
|
for (let i = 0; i < 1000; i++) {
|
|
void t.rawSet(`key_${i}`, i);
|
|
}
|
|
let sum = 0;
|
|
for (let i = 0; i < 1000; i++) {
|
|
sum += t.rawGet(`key_${i}`) as number;
|
|
}
|
|
return sum;
|
|
});
|
|
|
|
// --- Integer key set/get ---
|
|
|
|
bench("LuaTable: integer key set+get (1k ops)", () => {
|
|
const t = new LuaTable();
|
|
for (let i = 1; i <= 1000; i++) {
|
|
void t.set(i, i);
|
|
}
|
|
let sum = 0;
|
|
for (let i = 1; i <= 1000; i++) {
|
|
sum += t.get(i) as number;
|
|
}
|
|
return sum;
|
|
});
|
|
|
|
bench("LuaTable: integer key rawSet+rawGet (1k ops)", () => {
|
|
const t = new LuaTable();
|
|
for (let i = 1; i <= 1000; i++) {
|
|
void t.rawSet(i, i);
|
|
}
|
|
let sum = 0;
|
|
for (let i = 1; i <= 1000; i++) {
|
|
sum += t.rawGet(i) as number;
|
|
}
|
|
return sum;
|
|
});
|
|
|
|
// --- has() ---
|
|
|
|
const hasTable = new LuaTable();
|
|
for (let i = 0; i < 100; i++) void hasTable.set(`k${i}`, i);
|
|
for (let i = 1; i <= 100; i++) void hasTable.set(i, i);
|
|
|
|
bench("LuaTable: has() string key (100 lookups)", () => {
|
|
let count = 0;
|
|
for (let i = 0; i < 100; i++) {
|
|
if (hasTable.has(`k${i}`)) count++;
|
|
}
|
|
return count;
|
|
});
|
|
|
|
bench("LuaTable: has() integer key (100 lookups)", () => {
|
|
let count = 0;
|
|
for (let i = 1; i <= 100; i++) {
|
|
if (hasTable.has(i)) count++;
|
|
}
|
|
return count;
|
|
});
|
|
|
|
// --- keys() ---
|
|
|
|
const keysTable10 = new LuaTable();
|
|
for (let i = 0; i < 10; i++) void keysTable10.set(`k${i}`, i);
|
|
|
|
const keysTable100 = new LuaTable();
|
|
for (let i = 0; i < 100; i++) void keysTable100.set(`k${i}`, i);
|
|
|
|
bench("LuaTable: keys() on 10-key table", () => {
|
|
return keysTable10.keys();
|
|
});
|
|
|
|
bench("LuaTable: keys() on 100-key table", () => {
|
|
return keysTable100.keys();
|
|
});
|
|
|
|
// --- length getter ---
|
|
|
|
const lenTable = new LuaTable();
|
|
for (let i = 1; i <= 1000; i++) void lenTable.set(i, i);
|
|
|
|
bench("LuaTable: length getter (1000-element array)", () => {
|
|
return lenTable.length;
|
|
});
|
|
|
|
// --- Append pattern: t[#t+1] = v ---
|
|
|
|
bench("LuaTable: append pattern t[#t+1]=v (1k)", () => {
|
|
const t = new LuaTable();
|
|
for (let i = 0; i < 1000; i++) {
|
|
void t.set(t.length + 1, i);
|
|
}
|
|
return t;
|
|
});
|
|
|
|
// --- toJS / toJSObject / toJSArray ---
|
|
|
|
const convArrayTable = jsToLuaValue(medArray) as LuaTable;
|
|
const convObjTable = jsToLuaValue(medObj) as LuaTable;
|
|
const convNestedTable = jsToLuaValue(nestedData) as LuaTable;
|
|
|
|
bench("LuaTable: toJSArray (100 elements)", () => {
|
|
return convArrayTable.toJSArray(sf);
|
|
});
|
|
|
|
bench("LuaTable: toJSObject (100 keys)", () => {
|
|
return convObjTable.toJSObject(sf);
|
|
});
|
|
|
|
bench("LuaTable: toJS nested (100 objects)", () => {
|
|
return convNestedTable.toJS(sf);
|
|
});
|
|
|
|
// --- luaValueToJS roundtrip ---
|
|
|
|
bench("luaValueToJS: array table (100 elements)", () => {
|
|
return luaValueToJS(convArrayTable, sf);
|
|
});
|
|
|
|
bench("luaValueToJS: object table (100 keys)", () => {
|
|
return luaValueToJS(convObjTable, sf);
|
|
});
|
|
|
|
// --- Iteration pattern (pairs-like) ---
|
|
|
|
bench("LuaTable: iteration keys()+get() (100 string keys)", () => {
|
|
const keys = keysTable100.keys();
|
|
let sum = 0;
|
|
for (const k of keys) {
|
|
sum += keysTable100.get(k) as number;
|
|
}
|
|
return sum;
|
|
});
|
|
|
|
bench("LuaTable: iteration keys()+rawGet() (100 string keys)", () => {
|
|
const keys = keysTable100.keys();
|
|
let sum = 0;
|
|
for (const k of keys) {
|
|
sum += keysTable100.rawGet(k) as number;
|
|
}
|
|
return sum;
|
|
});
|