y
This commit is contained in:
parent
61718e2981
commit
f657b6a4a4
94 changed files with 3970 additions and 1241 deletions
77
scripts/performance_cleanup_regression_audit.js
Normal file
77
scripts/performance_cleanup_regression_audit.js
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
"use strict";
|
||||
|
||||
const assert = require("assert");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const vm = require("vm");
|
||||
const ROOT = path.resolve(__dirname, "..");
|
||||
const read = rel => fs.readFileSync(path.join(ROOT, rel), "utf8");
|
||||
|
||||
const render = read("js/render.js");
|
||||
assert(!render.includes("insertionSortNearPrevious"), "custom insertion sort still exists");
|
||||
assert(!render.includes("_renderPrevDynamicLayeredIds") && !render.includes("_renderBackSortMap"), "previous-order render bookkeeping still exists");
|
||||
assert(render.includes("dynamicBack.sort(compareBackItems)") && render.includes("dynamicLayered.sort(compareRenderEntries)"), "native render sort is not active");
|
||||
console.log("[OK] previous-order Map and custom insertion sort are removed");
|
||||
|
||||
const pathfinding = read("js/world_pathfinding_system.js");
|
||||
assert(!pathfinding.includes("_sharedRouteCache") && !pathfinding.includes("trySharedRoute") && !pathfinding.includes("storeSharedRoute"), "shared route cache still exists");
|
||||
assert(pathfinding.includes("actor._routeCache"), "actor-local route cache was removed accidentally");
|
||||
console.log("[OK] shared route cache is removed while actor-local throttling remains");
|
||||
|
||||
const profiler = read("js/perf_profiler.js");
|
||||
const budget = read("js/world_spatial_budget.js");
|
||||
assert(profiler.includes("diagnosticsEnabled"), "diagnostic-mode gate is missing");
|
||||
assert(budget.includes("diagnostics ?") && budget.includes("this.workStats = diagnostics ?"), "production detailed diagnostic allocation is still unconditional");
|
||||
assert(profiler.includes("transitionHoldSeconds") && profiler.includes("pendingProfileSeconds"), "performance-profile hysteresis hold timers are missing");
|
||||
console.log("[OK] production diagnostics are gated and auto profile switching uses hysteresis");
|
||||
|
||||
const environment = read("js/world_environment.js");
|
||||
assert(environment.includes("`${this.routingObstacleVersion || 0}:${qx},${qy},${qr},${cacheLimit},${maxRects}`"), "obstacle cache is not keyed by routingObstacleVersion only");
|
||||
assert(!environment.includes("`${this.spatialVersion || 0}:${this.spatialDirtyMarksTotal || 0}:${qx}"), "obstacle cache still invalidates on generic spatial movement");
|
||||
console.log("[OK] obstacle cache invalidation is isolated from generic spatial movement");
|
||||
|
||||
const simCore = read("js/sim_core.js");
|
||||
const start = simCore.indexOf("class SpatialGrid {");
|
||||
const end = simCore.indexOf("\nfunction drawHeartShape", start);
|
||||
assert(start >= 0 && end > start, "SpatialGrid source could not be isolated");
|
||||
const context = { console, Map, Set, Math, Number, Array, globalThis: {} };
|
||||
vm.createContext(context);
|
||||
vm.runInContext(`${simCore.slice(start, end)}\nglobalThis.SpatialGrid = SpatialGrid;`, context);
|
||||
const SpatialGrid = context.globalThis.SpatialGrid;
|
||||
const grid = new SpatialGrid(100);
|
||||
const a = { id: "a", x: 10, y: 10, dead: false };
|
||||
const b = { id: "b", x: 40, y: 40, dead: false };
|
||||
grid.rebuildTarinai([a, b]);
|
||||
const firstKey = a._spatialTarinaiCellKey;
|
||||
a.x = 50;
|
||||
assert.strictEqual(grid.syncTarinai([a, b]), 0, "same-cell movement should not rewrite the grid");
|
||||
a.x = 150;
|
||||
assert.strictEqual(grid.syncTarinai([a, b]), 1, "cell crossing should update exactly one entity");
|
||||
assert.notStrictEqual(a._spatialTarinaiCellKey, firstKey, "cell key did not change after crossing");
|
||||
b.dead = true;
|
||||
assert(grid.syncTarinai([a, b]) >= 1, "dead entity was not removed incrementally");
|
||||
assert(!grid._indexedTarinai.has(b), "dead entity remains in the Tarinai spatial index");
|
||||
console.log("[OK] Tarinai spatial grid updates only cell crossings/removals instead of full rebuilds");
|
||||
|
||||
class World {}
|
||||
global.World = World;
|
||||
global.TarinaiHistory = { trimMemory() { return 0; } };
|
||||
require(path.join(ROOT, "js", "world_spatial_budget.js"));
|
||||
const world = new World();
|
||||
world.time = 100;
|
||||
world.tarinai = Array.from({ length: 120 }, (_, i) => ({ id: `T${i}`, dead: false, relationships: { D: { affinity: 1 } } }));
|
||||
world.liveTarinai = new Map(world.tarinai.map(t => [t.id, { target: t }]));
|
||||
world._deadTarinaiIdsPendingCleanup = new Set(["D"]);
|
||||
world.tarinaiCollisionMemo = new Map();
|
||||
world.relationNotices = {};
|
||||
world.fightPairCooldowns = {};
|
||||
world.resolvedFightIds = {};
|
||||
assert(world.queueTarinaiRuntimeCachePrune("audit", { resetRelationPeerCaches: true }), "cleanup job was not queued");
|
||||
world.processTarinaiRuntimeCachePruneStep(24);
|
||||
assert(world._tarinaiRuntimePruneJob, "cleanup finished in one frame instead of being chunked");
|
||||
assert.strictEqual(world._tarinaiRuntimePruneJob.cursor, 24, "cleanup chunk size was not respected");
|
||||
while (world._tarinaiRuntimePruneJob) world.processTarinaiRuntimeCachePruneStep(24);
|
||||
assert(world.tarinai.every(t => !Object.prototype.hasOwnProperty.call(t.relationships, "D")), "chunked cleanup left dead references behind");
|
||||
console.log("[OK] death-reference cleanup runs in bounded per-frame chunks");
|
||||
|
||||
console.log("Performance cleanup regression audit passed.");
|
||||
Loading…
Add table
Add a link
Reference in a new issue