From 3276566ea5012a25a31a69cfcbc6ddb99d774121 Mon Sep 17 00:00:00 2001 From: alicesaidhi <166900055+alicesaidhi@users.noreply.github.com> Date: Tue, 17 Sep 2024 02:40:31 +0200 Subject: [PATCH] Improve benchmark code (#84) * Create general.luau * add query * update query * world:target bench * change requires * add relationship benchmark --- benches/general.luau | 198 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 benches/general.luau diff --git a/benches/general.luau b/benches/general.luau new file mode 100644 index 00000000..3f2247b9 --- /dev/null +++ b/benches/general.luau @@ -0,0 +1,198 @@ +local jecs = require("@jecs") +local testkit = require("@testkit") + +local BENCH, START = testkit.benchmark() + +local function TITLE(s: string) + print() + print(testkit.color.white(s)) +end + +local N = 2^17 + +local pair = jecs.pair + +do TITLE "create" + local world = jecs.World.new() + + BENCH("entity", function() + for i = 1, START(N) do + world:entity() + end + end) + + local A, B = world:entity(), world:entity() + + BENCH("pair", function() + for i = 1, START(N) do + jecs.pair(A, B) + end + end) + +end + +do TITLE "set" + + local world = jecs.World.new() + local A = world:entity() + + local entities = table.create(N) + + for i = 1, N do + entities[i] = world:entity() + end + + BENCH("add", function() + for i = 1, START(N) do + world:set(entities[i], A, 1) + end + end) + + BENCH("set", function() + for i = 1, START(N) do + world:set(entities[i], A, 2) + end + end) + + BENCH("remove", function() + for i = 1, START(N) do + world:remove(entities[i], A) + end + end) +end + +-- we have a separate benchmark for relationships. +-- this is due to that relationships have a very high id compared to normal +-- components, which cause them to get added into the hashmap portion. +do TITLE "set relationship" + + local world = jecs.World.new() + local A = world:entity() + + local entities = table.create(N) + + for i = 1, N do + entities[i] = world:entity() + world:set(entities[i], A, 1) + end + + local pair = jecs.pair(A, world:entity()) + + BENCH("add", function() + for i = 1, START(N) do + world:set(entities[i], pair, 1) + end + end) + + BENCH("set", function() + for i = 1, START(N) do + world:set(entities[i], pair, 2) + end + end) + + BENCH("remove", function() + for i = 1, START(N) do + world:remove(entities[i], pair) + end + end) +end + +do TITLE "get" + + local world = jecs.World.new() + local A, B, C, D = world:entity(), world:entity(), world:entity(), world:entity() + + local entities = table.create(N) + + for i = 1, N do + entities[i] = world:entity() + world:set(entities[i], A, 1) + world:set(entities[i], B, 1) + world:set(entities[i], C, 1) + world:set(entities[i], D, 1) + end + + BENCH("1", function() + for i = 1, START(N) do + world:get(entities[i], A) + end + end) + + BENCH("2", function() + for i = 1, START(N) do + world:get(entities[i], A, B) + end + end) + + BENCH("3", function() + for i = 1, START(N) do + world:get(entities[i], A, B, C) + end + end) + + BENCH("4", function() + for i = 1, START(N) do + world:get(entities[i], A, B, C, D) + end + end) +end + +do TITLE "target" + + BENCH("1st target", function() + local world = jecs.World.new() + local A, B, C, D = world:entity(), world:entity(), world:entity(), world:entity() + local entities = table.create(N) + + for i = 1, N do + local ent = world:entity() + entities[i] = ent + + world:set(ent, pair(A, A)) + world:set(ent, pair(A, B)) + world:set(ent, pair(A, C)) + world:set(ent, pair(A, D)) + end + + for i = 1, START(N) do + world:target(entities[i], A) + end + end) + +end + +--- this benchmark is used to view how fragmentation affects query performance +--- we use this by determining how many entities should fit per arcehtype, instead +--- of creating x amount of archetypes. this would scale better with any amount of +--- entities. +do TITLE(`query {N} entities`) + + local function view_bench(n: number) + BENCH(`{n} entities per archetype`, function() + local world = jecs.World.new() + local A, B, C, D = world:entity(), world:entity(), world:entity(), world:entity() + + for i = 1, N, n do + local ct = world:entity() + for j = 1, n do + local id = world:entity() + world:set(id, A, true) + world:set(id, B, true) + world:set(id, C, true) + world:set(id, D, true) + world:set(id, ct, true) + end + end + + START() + for id in world:query(A, B, C, D) do + end + + end) + end + + for i = 13, 0, -1 do + view_bench(2^i) + end + +end