local evo = require 'evolved' local basics = require 'develop.basics' local tiny = require 'develop.3rdparty.tiny' evo.debug_mode(false) local N = 1000 print '----------------------------------------' basics.describe_bench(string.format('Common Benchmarks: Tiny Entity Cycle | %d entities', N), function(world) world:update() end, function() local world = tiny.world() for _ = 1, N do world:addEntity({ a = 0 }) end local A = tiny.processingSystem() A.filter = tiny.requireAll('a') A.process = function(_, e) world:addEntity({ b = e.a }) end A.postProcess = function(_) world:refresh() end local B = tiny.processingSystem() B.filter = tiny.requireAll('b') B.process = function(_, e) world:removeEntity(e) end B.postProcess = function(_) world:refresh() end world:addSystem(A) world:addSystem(B) world:refresh() return world end) basics.describe_bench(string.format('Common Benchmarks: Evolved Entity Cycle | %d entities', N), function(world) evo.process(world) end, function() local world = evo.builder() :destruction_policy(evo.DESTRUCTION_POLICY_DESTROY_ENTITY) :spawn() local a = evo.builder():set(world):spawn() local b = evo.builder():set(world):spawn() local query_a = evo.builder():set(world):include(a):spawn() local query_b = evo.builder():set(world):include(b):spawn() local prefab_a = evo.builder():prefab():set(world):set(a, 0):spawn() local prefab_b = evo.builder():prefab():set(world):set(b, 0):spawn() evo.multi_clone(N, prefab_a) evo.builder() :set(world):group(world):query(query_a) :execute(function(chunk, _, entity_count) local as = chunk:components(a) local entity_bs = evo.multi_clone(entity_count, prefab_b) for i = 1, entity_count do evo.set(entity_bs[i], b, as[i]) end end):spawn() evo.builder() :set(world):group(world):query(query_b) :prologue(function() evo.batch_destroy(query_b) end):spawn() return world end, function(world) evo.destroy(world) end) print '----------------------------------------' basics.describe_bench(string.format('Common Benchmarks: Tiny Simple Iteration | %d entities', N), function(world) world:update() end, function() local world = tiny.world() for _ = 1, N do world:addEntity({ a = 0, b = 0 }) world:addEntity({ a = 0, b = 0, c = 0 }) world:addEntity({ a = 0, b = 0, c = 0, d = 0 }) world:addEntity({ a = 0, b = 0, c = 0, e = 0 }) end local AB = tiny.processingSystem() AB.filter = tiny.requireAll('a', 'b') AB.process = function(_, e) e.a, e.b = e.b, e.a end local CD = tiny.processingSystem() CD.filter = tiny.requireAll('c', 'd') CD.process = function(_, e) e.c, e.d = e.d, e.c end local CE = tiny.processingSystem() CE.filter = tiny.requireAll('c', 'e') CE.process = function(_, e) e.c, e.e = e.e, e.c end world:addSystem(AB) world:addSystem(CD) world:addSystem(CE) world:refresh() return world end) basics.describe_bench(string.format('Common Benchmarks: Evolved Simple Iteration | %d entities', N), function(world) evo.process(world) end, function() local world = evo.builder() :destruction_policy(evo.DESTRUCTION_POLICY_DESTROY_ENTITY) :spawn() local a = evo.builder():set(world):spawn() local b = evo.builder():set(world):spawn() local c = evo.builder():set(world):spawn() local d = evo.builder():set(world):spawn() local e = evo.builder():set(world):spawn() local query_ab = evo.builder():set(world):include(a, b):spawn() local query_cd = evo.builder():set(world):include(c, d):spawn() local query_ce = evo.builder():set(world):include(c, e):spawn() evo.multi_spawn(N, { [world] = true, [a] = 0, [b] = 0 }) evo.multi_spawn(N, { [world] = true, [a] = 0, [b] = 0, [c] = 0 }) evo.multi_spawn(N, { [world] = true, [a] = 0, [b] = 0, [c] = 0, [d] = 0 }) evo.multi_spawn(N, { [world] = true, [a] = 0, [b] = 0, [c] = 0, [e] = 0 }) evo.builder() :set(world):group(world):query(query_ab) :execute(function(chunk, _, entity_count) local as, bs = chunk:components(a, b) for i = 1, entity_count do as[i], bs[i] = bs[i], as[i] end end):spawn() evo.builder() :set(world):group(world):query(query_cd) :execute(function(chunk, _, entity_count) local cs, ds = chunk:components(c, d) for i = 1, entity_count do cs[i], ds[i] = ds[i], cs[i] end end):spawn() evo.builder() :set(world):group(world):query(query_ce) :execute(function(chunk, _, entity_count) local cs, es = chunk:components(c, e) for i = 1, entity_count do cs[i], es[i] = es[i], cs[i] end end):spawn() return world end, function(world) evo.destroy(world) end) print '----------------------------------------' basics.describe_bench(string.format('Common Benchmarks: Tiny Packed Iteration | %d entities', N), function(world) world:update() end, function() local world = tiny.world() for _ = 1, N do world:addEntity({ a = 0, b = 0, c = 0, d = 0, e = 0 }) end local A = tiny.processingSystem() A.filter = tiny.requireAll('a') A.process = function(_, e) e.a = e.a * 2 end local B = tiny.processingSystem() B.filter = tiny.requireAll('b') B.process = function(_, e) e.b = e.b * 2 end local C = tiny.processingSystem() C.filter = tiny.requireAll('c') C.process = function(_, e) e.c = e.c * 2 end local D = tiny.processingSystem() D.filter = tiny.requireAll('d') D.process = function(_, e) e.d = e.d * 2 end local E = tiny.processingSystem() E.filter = tiny.requireAll('e') E.process = function(_, e) e.e = e.e * 2 end world:addSystem(A) world:addSystem(B) world:addSystem(C) world:addSystem(D) world:addSystem(E) world:refresh() return world end) basics.describe_bench(string.format('Common Benchmarks: Evolved Packed Iteration | %d entities', N), function(world) evo.process(world) end, function() local world = evo.builder() :destruction_policy(evo.DESTRUCTION_POLICY_DESTROY_ENTITY) :spawn() local a = evo.builder():set(world):spawn() local b = evo.builder():set(world):spawn() local c = evo.builder():set(world):spawn() local d = evo.builder():set(world):spawn() local e = evo.builder():set(world):spawn() local query_a = evo.builder():set(world):include(a):spawn() local query_b = evo.builder():set(world):include(b):spawn() local query_c = evo.builder():set(world):include(c):spawn() local query_d = evo.builder():set(world):include(d):spawn() local query_e = evo.builder():set(world):include(e):spawn() evo.multi_spawn(N, { [world] = true, [a] = 0, [b] = 0, [c] = 0, [d] = 0, [e] = 0 }) evo.builder() :set(world):group(world):query(query_a) :execute(function(chunk, _, entity_count) local as = chunk:components(a) for i = 1, entity_count do as[i] = as[i] * 2 end end):spawn() evo.builder() :set(world):group(world):query(query_b) :execute(function(chunk, _, entity_count) local bs = chunk:components(b) for i = 1, entity_count do bs[i] = bs[i] * 2 end end):spawn() evo.builder() :set(world):group(world):query(query_c) :execute(function(chunk, _, entity_count) local cs = chunk:components(c) for i = 1, entity_count do cs[i] = cs[i] * 2 end end):spawn() evo.builder() :set(world):group(world):query(query_d) :execute(function(chunk, _, entity_count) local ds = chunk:components(d) for i = 1, entity_count do ds[i] = ds[i] * 2 end end):spawn() evo.builder() :set(world):group(world):query(query_e) :execute(function(chunk, _, entity_count) local es = chunk:components(e) for i = 1, entity_count do es[i] = es[i] * 2 end end):spawn() return world end, function(world) evo.destroy(world) end) print '----------------------------------------' basics.describe_bench(string.format('Common Benchmarks: Tiny Fragmented Iteration | %d entities', N), function(world) world:update() end, function() local world = tiny.world() ---@type string[] local chars = {} for i = 1, 26 do chars[i] = string.char(string.byte('a') + i - 1) end for i, char in ipairs(chars) do for _ = 1, N do world:addEntity({ [char] = i, data = i }) end end local Data = tiny.processingSystem() Data.filter = tiny.requireAll('data') Data.process = function(_, e) e.data = e.data * 2 end local Last = tiny.processingSystem() Last.filter = tiny.requireAll('z') Last.process = function(_, e) e.z = e.z * 2 end world:addSystem(Data) world:addSystem(Last) world:refresh() return world end) basics.describe_bench(string.format('Common Benchmarks: Evolved Fragmented Iteration | %d entities', N), function(world) evo.process(world) end, function() local world = evo.builder() :destruction_policy(evo.DESTRUCTION_POLICY_DESTROY_ENTITY) :spawn() local data = evo.spawn { [world] = true } local chars = evo.multi_spawn(26, { [world] = true }) local query_data = evo.builder():set(world):include(data):spawn() local query_z = evo.builder():set(world):include(chars[#chars]):spawn() for i = 1, #chars do evo.multi_spawn(N, { [world] = true, [chars[i]] = i, [data] = i }) end evo.builder() :set(world):group(world):query(query_data) :execute(function(chunk, _, entity_count) local datas = chunk:components(data) for i = 1, entity_count do datas[i] = datas[i] * 2 end end):spawn() evo.builder() :set(world):group(world):query(query_z) :execute(function(chunk, _, entity_count) local zs = chunk:components(chars[#chars]) for i = 1, entity_count do zs[i] = zs[i] * 2 end end):spawn() return world end, function(world) evo.destroy(world) end)