From 28a44c38543960df8e92bac5767560c650af9ab6 Mon Sep 17 00:00:00 2001 From: Ramine Agoune Date: Fri, 18 Sep 2026 12:54:53 +0000 Subject: [PATCH] perf: zero-allocation single-component add (P1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AddComponent, the non-generic config path and AddTag resolved their destination through getNextArchetype with a one-element variadic slice, after boxing the component into ComponentInterface to read its id: two heap allocations per add (the variadic slice escapes because the multi-component branch may retain it as an archetype Type). They now read the id from the typed value and hop the archetype graph directly (archetypeAfterAdd). BenchmarkAddVolt (5800X): 6.27 ms/op, 200000 allocs/op → 4.0 ms/op, 0 allocs/op. --- component.go | 2 +- register.go | 2 +- tag.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/component.go b/component.go index f7ec1e4..d3a5587 100644 --- a/component.go +++ b/component.go @@ -56,7 +56,7 @@ func AddComponent[T ComponentInterface](world *World, entityId EntityId, compone return fmt.Errorf("the entity %d already owns the component %d", entityId, componentId) } - archetype := world.getNextArchetype(entityRecord, world.getComponentsIds(component)...) + archetype := world.archetypeAfterAdd(entityRecord.archetypeId, componentId) err := addComponentsToArchetype1(world, entityRecord, archetype, component) if err != nil { return fmt.Errorf("the component %d cannot be added to entity %d: %w", componentId, entityId, err) diff --git a/register.go b/register.go index 5a6f4a6..072d08d 100644 --- a/register.go +++ b/register.go @@ -36,7 +36,7 @@ func (componentConfig *ComponentConfig[T]) addComponent(world *World, entityId E componentConfig.builderFn(&t, configuration) entityRecord := world.entities[entityId.Index()] - archetype := world.getNextArchetype(entityRecord, componentConfig.id) + archetype := world.archetypeAfterAdd(entityRecord.archetypeId, componentConfig.id) err := addComponentsToArchetype1[T](world, entityRecord, archetype, t) return err diff --git a/tag.go b/tag.go index 8de6cb5..f49ade7 100644 --- a/tag.go +++ b/tag.go @@ -27,7 +27,7 @@ func (world *World) AddTag(tagId TagId, entityId EntityId) error { } entityRecord := world.entities[entityId.Index()] - archetype := world.getNextArchetype(entityRecord, tagId) + archetype := world.archetypeAfterAdd(entityRecord.archetypeId, tagId) oldArchetype := world.getArchetype(entityRecord) if archetype.Id != oldArchetype.Id {