Optimize idr_r removal by 35%

This commit is contained in:
Ukendio 2025-12-21 19:21:42 +01:00
parent 3ebb2334da
commit aa63051db3
2 changed files with 66 additions and 6 deletions

View file

@ -3246,22 +3246,33 @@ local function world_new()
local records = idr_r.records
for archetype_id in archetype_ids do
local idr_r_archetype = archetypes[archetype_id]
local node = idr_r_archetype
-- local node = idr_r_archetype
local entities = idr_r_archetype.entities
local tr = records[archetype_id]
local tr_count = counts[archetype_id]
local idr_r_types = idr_r_archetype.types
local dst = table.clone(idr_r_types)
for i = tr, tr + tr_count - 1 do
local id = idr_r_types[i]
node = archetype_traverse_remove(world, id, node)
local at = table.find(dst, id)
if at then
table.remove(dst, at)
end
-- node = archetype_traverse_remove(world, id, node)
local on_remove = component_index[id].on_remove
if on_remove then
-- NOTE(marcus): Since hooks can move the entities
-- assumptions about which archetype it jumps to is
-- diminished. We assume that people who delete
-- relation will never have hooks on them.
for _, entity in entities do
on_remove(entity, id)
end
end
end
local node = archetype_ensure(world, dst)
for i = #entities, 1, -1 do
local e = entities[i]
local r = entity_index_try_get_unsafe(e) :: record

View file

@ -24,6 +24,59 @@ type Id<T=unknown> = jecs.Id<T>
local entity_visualiser = require("@modules/entity_visualiser")
local dwi = entity_visualiser.stringify
TEST("optimize idr_r removal", function()
local pair = jecs.pair
local world = jecs.world()
local rel = world:component()
local A = world:component()
local B = world:component()
local t1 = world:entity()
local t2 = world:entity()
local entities = {} :: { jecs.Entity }
for i = 1, 10 do
local e1 = world:entity()
local e2 = world:entity()
world:set(e1, A, true)
world:set(e2, A, true)
world:add(e1, pair(B, t1))
world:add(e1, pair(B, t2))
world:add(e2, pair(B, t1))
world:add(e2, pair(B, t2))
table.insert(entities, e1)
table.insert(entities, e2)
end
local e1 = world:entity()
local e2 = world:entity()
table.insert(entities, e1)
table.insert(entities, e2)
world:set(e1, A, true)
world:set(e2, A, true)
world:add(e1, pair(B, t1))
world:add(e1, pair(B, t2))
world:add(e2, pair(B, t1))
world:add(e2, pair(B, t2))
BENCH("delete B", function()
world:delete(B)
end)
for _, e in entities do
CHECK(world:has(e, A))
CHECK(not world:target(e, B))
CHECK(not world:target(e, B))
end
end)
TEST("deleting t1's archetype before invoking its onremove hooks", function()
local pair = jecs.pair
local world = jecs.world()
@ -96,10 +149,6 @@ TEST("reproduce idr_t nil archetype bug", function()
-- Removing this, but keeping Animator on the other 2 causes it to stop happening
world:set(trackEntity1, cts.VelocitizeAnimationWeight, 0)
print("delete root")
world:delete(root)
print("---")
for entityId, info in trackedEntities do
if world:contains(entityId) and not world:parent(entityId :: any) then
print(`bugged entity found: {entityId}`)