mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-13 03:29:08 +07:00
slightly improve required fragments perf
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
|
||||
## Backlog
|
||||
|
||||
- Improve the performance of required fragments by caching first-level required chunks.
|
||||
- Improve the performance of builders that are used multiple times by caching hint chunks.
|
||||
- Queries can cache major chunks to avoid finding them every time.
|
||||
- observers and events
|
||||
@@ -14,3 +13,7 @@
|
||||
|
||||
- We can return deferred status from modifying operations and spawn/clone methods.
|
||||
- Should we make one builder:build method instead of :spawn and :clone?
|
||||
|
||||
## Known Issues
|
||||
|
||||
- Required fragments are slower than they should be
|
||||
|
||||
@@ -9,10 +9,6 @@ local F1, F2, F3, F4, F5 = evo.id(5)
|
||||
|
||||
local Q1 = evo.builder():include(F1):spawn()
|
||||
|
||||
local B1 = evo.builder()
|
||||
local B3 = evo.builder()
|
||||
local B5 = evo.builder()
|
||||
|
||||
local R1 = evo.builder():require(F1):spawn()
|
||||
local R3 = evo.builder():require(F1, F2, F3):spawn()
|
||||
local R5 = evo.builder():require(F1, F2, F3, F4, F5):spawn()
|
||||
@@ -103,11 +99,10 @@ print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 component', N),
|
||||
function()
|
||||
local set, spawn = B1.set, B1.spawn
|
||||
local builder = evo.builder()
|
||||
|
||||
for _ = 1, N do
|
||||
set(B1, F1)
|
||||
spawn(B1)
|
||||
builder:set(F1):spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
@@ -115,13 +110,10 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 components', N),
|
||||
function()
|
||||
local set, spawn = B3.set, B3.spawn
|
||||
local builder = evo.builder()
|
||||
|
||||
for _ = 1, N do
|
||||
set(B3, F1)
|
||||
set(B3, F2)
|
||||
set(B3, F3)
|
||||
spawn(B3)
|
||||
builder:set(F1):set(F2):set(F3):spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
@@ -129,15 +121,10 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 components', N),
|
||||
function()
|
||||
local set, spawn = B5.set, B5.spawn
|
||||
local builder = evo.builder()
|
||||
|
||||
for _ = 1, N do
|
||||
set(B5, F1)
|
||||
set(B5, F2)
|
||||
set(B5, F3)
|
||||
set(B5, F4)
|
||||
set(B5, F5)
|
||||
spawn(B5)
|
||||
builder:set(F1):set(F2):set(F3):set(F4):set(F5):spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
@@ -147,11 +134,10 @@ print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 required component', N),
|
||||
function()
|
||||
local set, spawn = B1.set, B1.spawn
|
||||
local builder = evo.builder()
|
||||
|
||||
for _ = 1, N do
|
||||
set(B1, R1)
|
||||
spawn(B1)
|
||||
builder:set(R1):spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
@@ -159,11 +145,10 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 required components', N),
|
||||
function()
|
||||
local set, spawn = B3.set, B3.spawn
|
||||
local builder = evo.builder()
|
||||
|
||||
for _ = 1, N do
|
||||
set(B3, R3)
|
||||
spawn(B3)
|
||||
builder:set(R3):spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
@@ -171,11 +156,10 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 required components', N),
|
||||
function()
|
||||
local set, spawn = B5.set, B5.spawn
|
||||
local builder = evo.builder()
|
||||
|
||||
for _ = 1, N do
|
||||
set(B5, R5)
|
||||
spawn(B5)
|
||||
builder:set(R5):spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
|
||||
85
evolved.lua
85
evolved.lua
@@ -1683,26 +1683,44 @@ function __chunk_get_all_components(chunk, place, ...)
|
||||
end
|
||||
end
|
||||
|
||||
---@param chunk evolved.chunk
|
||||
---@param ini_chunk evolved.chunk
|
||||
---@param req_fragment_set table<evolved.fragment, integer>
|
||||
---@param req_fragment_list evolved.fragment[]
|
||||
---@param req_fragment_count integer
|
||||
---@return integer
|
||||
---@nodiscard
|
||||
function __chunk_required_fragments(chunk, req_fragment_set, req_fragment_list, req_fragment_count)
|
||||
function __chunk_required_fragments(ini_chunk, req_fragment_set, req_fragment_list, req_fragment_count)
|
||||
---@type evolved.fragment[]
|
||||
local fragment_stack = __acquire_table(__table_pool_tag.fragment_list)
|
||||
local fragment_stack_size = 0
|
||||
|
||||
do
|
||||
local chunk_fragment_list = chunk.__fragment_list
|
||||
local chunk_fragment_count = chunk.__fragment_count
|
||||
local ini_fragment_set = ini_chunk.__fragment_set
|
||||
local ini_fragment_list = ini_chunk.__fragment_list
|
||||
local ini_fragment_count = ini_chunk.__fragment_count
|
||||
|
||||
__lua_table_move(
|
||||
chunk_fragment_list, 1, chunk_fragment_count,
|
||||
fragment_stack_size + 1, fragment_stack)
|
||||
for ini_fragment_index = 1, ini_fragment_count do
|
||||
local ini_fragment = ini_fragment_list[ini_fragment_index]
|
||||
|
||||
fragment_stack_size = fragment_stack_size + chunk_fragment_count
|
||||
local ini_fragment_requires = __sorted_requires[ini_fragment]
|
||||
local ini_fragment_require_list = ini_fragment_requires and ini_fragment_requires.__item_list
|
||||
local ini_fragment_require_count = ini_fragment_requires and ini_fragment_requires.__item_count or 0
|
||||
|
||||
for required_fragment_index = 1, ini_fragment_require_count do
|
||||
local required_fragment = ini_fragment_require_list[required_fragment_index]
|
||||
|
||||
if ini_fragment_set[required_fragment] or req_fragment_set[required_fragment] then
|
||||
-- this fragment has already been gathered
|
||||
else
|
||||
req_fragment_count = req_fragment_count + 1
|
||||
req_fragment_set[required_fragment] = req_fragment_count
|
||||
req_fragment_list[req_fragment_count] = required_fragment
|
||||
|
||||
if __sorted_requires[required_fragment] then
|
||||
fragment_stack_size = fragment_stack_size + 1
|
||||
fragment_stack[fragment_stack_size] = required_fragment
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
while fragment_stack_size > 0 do
|
||||
@@ -1718,15 +1736,17 @@ function __chunk_required_fragments(chunk, req_fragment_set, req_fragment_list,
|
||||
for fragment_require_index = 1, fragment_require_count do
|
||||
local required_fragment = fragment_require_list[fragment_require_index]
|
||||
|
||||
if req_fragment_set[required_fragment] then
|
||||
if ini_fragment_set[required_fragment] or req_fragment_set[required_fragment] then
|
||||
-- this fragment has already been gathered
|
||||
else
|
||||
req_fragment_count = req_fragment_count + 1
|
||||
req_fragment_set[required_fragment] = req_fragment_count
|
||||
req_fragment_list[req_fragment_count] = required_fragment
|
||||
|
||||
fragment_stack_size = fragment_stack_size + 1
|
||||
fragment_stack[fragment_stack_size] = required_fragment
|
||||
if __sorted_requires[required_fragment] then
|
||||
fragment_stack_size = fragment_stack_size + 1
|
||||
fragment_stack[fragment_stack_size] = required_fragment
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1735,20 +1755,41 @@ function __chunk_required_fragments(chunk, req_fragment_set, req_fragment_list,
|
||||
return req_fragment_count
|
||||
end
|
||||
|
||||
---@param fragment evolved.fragment
|
||||
---@param ini_chunk evolved.chunk
|
||||
---@param ini_fragment evolved.fragment
|
||||
---@param req_fragment_set table<evolved.fragment, integer>
|
||||
---@param req_fragment_list evolved.fragment[]
|
||||
---@param req_fragment_count integer
|
||||
---@return integer
|
||||
---@nodiscard
|
||||
function __fragment_required_fragments(fragment, req_fragment_set, req_fragment_list, req_fragment_count)
|
||||
function __fragment_required_fragments(ini_chunk, ini_fragment, req_fragment_set, req_fragment_list, req_fragment_count)
|
||||
---@type evolved.fragment[]
|
||||
local fragment_stack = __acquire_table(__table_pool_tag.fragment_list)
|
||||
local fragment_stack_size = 0
|
||||
|
||||
local ini_fragment_set = ini_chunk.__fragment_set
|
||||
|
||||
do
|
||||
fragment_stack_size = fragment_stack_size + 1
|
||||
fragment_stack[fragment_stack_size] = fragment
|
||||
local ini_fragment_requires = __sorted_requires[ini_fragment]
|
||||
local ini_fragment_require_list = ini_fragment_requires and ini_fragment_requires.__item_list
|
||||
local ini_fragment_require_count = ini_fragment_requires and ini_fragment_requires.__item_count or 0
|
||||
|
||||
for required_fragment_index = 1, ini_fragment_require_count do
|
||||
local required_fragment = ini_fragment_require_list[required_fragment_index]
|
||||
|
||||
if ini_fragment_set[required_fragment] or req_fragment_set[required_fragment] then
|
||||
-- this fragment has already been gathered
|
||||
else
|
||||
req_fragment_count = req_fragment_count + 1
|
||||
req_fragment_set[required_fragment] = req_fragment_count
|
||||
req_fragment_list[req_fragment_count] = required_fragment
|
||||
|
||||
if __sorted_requires[required_fragment] then
|
||||
fragment_stack_size = fragment_stack_size + 1
|
||||
fragment_stack[fragment_stack_size] = required_fragment
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
while fragment_stack_size > 0 do
|
||||
@@ -1764,15 +1805,17 @@ function __fragment_required_fragments(fragment, req_fragment_set, req_fragment_
|
||||
for fragment_require_index = 1, fragment_require_count do
|
||||
local required_fragment = fragment_require_list[fragment_require_index]
|
||||
|
||||
if req_fragment_set[required_fragment] then
|
||||
if ini_fragment_set[required_fragment] or req_fragment_set[required_fragment] then
|
||||
-- this fragment has already been gathered
|
||||
else
|
||||
req_fragment_count = req_fragment_count + 1
|
||||
req_fragment_set[required_fragment] = req_fragment_count
|
||||
req_fragment_list[req_fragment_count] = required_fragment
|
||||
|
||||
fragment_stack_size = fragment_stack_size + 1
|
||||
fragment_stack[fragment_stack_size] = required_fragment
|
||||
if __sorted_requires[required_fragment] then
|
||||
fragment_stack_size = fragment_stack_size + 1
|
||||
fragment_stack[fragment_stack_size] = required_fragment
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3155,7 +3198,7 @@ function __chunk_set(old_chunk, fragment, component)
|
||||
---@type evolved.fragment[]
|
||||
req_fragment_list = __acquire_table(__table_pool_tag.fragment_list)
|
||||
|
||||
req_fragment_count = __fragment_required_fragments(fragment,
|
||||
req_fragment_count = __fragment_required_fragments(ini_new_chunk, fragment,
|
||||
req_fragment_set, req_fragment_list, req_fragment_count)
|
||||
|
||||
for req_fragment_index = 1, req_fragment_count do
|
||||
@@ -5133,7 +5176,7 @@ function __evolved_set(entity, fragment, component)
|
||||
---@type evolved.fragment[]
|
||||
req_fragment_list = __acquire_table(__table_pool_tag.fragment_list)
|
||||
|
||||
req_fragment_count = __fragment_required_fragments(fragment,
|
||||
req_fragment_count = __fragment_required_fragments(ini_new_chunk, fragment,
|
||||
req_fragment_set, req_fragment_list, req_fragment_count)
|
||||
|
||||
for req_fragment_index = 1, req_fragment_count do
|
||||
|
||||
Reference in New Issue
Block a user