basic ECS spawner
This commit is contained in:
179
addons/gecs/tests/performance/test_indexing_perf.gd
Normal file
179
addons/gecs/tests/performance/test_indexing_perf.gd
Normal file
@@ -0,0 +1,179 @@
|
||||
## Component Indexing Performance Tests
|
||||
## Compares performance of using Script objects vs String paths as dictionary keys
|
||||
extends GdUnitTestSuite
|
||||
|
||||
var runner: GdUnitSceneRunner
|
||||
var world: World
|
||||
|
||||
|
||||
func before():
|
||||
runner = scene_runner("res://addons/gecs/tests/test_scene.tscn")
|
||||
world = runner.get_property("world")
|
||||
ECS.world = world
|
||||
|
||||
|
||||
func after_test():
|
||||
if world:
|
||||
world.purge(false)
|
||||
|
||||
|
||||
## Test dictionary lookup performance with String keys (current implementation)
|
||||
func test_string_key_lookup(scale: int, test_parameters := [[1000], [10000], [100000]]):
|
||||
# Create string-based dictionary
|
||||
var string_dict: Dictionary = {}
|
||||
|
||||
# Populate with component paths
|
||||
var component_types = [C_TestA, C_TestB, C_TestC, C_TestD]
|
||||
for comp_type in component_types:
|
||||
var path = comp_type.resource_path
|
||||
string_dict[path] = []
|
||||
for i in scale / 4:
|
||||
string_dict[path].append(i)
|
||||
|
||||
# Time lookups
|
||||
var time_ms = PerfHelpers.time_it(func():
|
||||
for i in 10000: # Many lookups
|
||||
var comp_type = component_types[i % 4]
|
||||
var _result = string_dict.get(comp_type.resource_path, [])
|
||||
)
|
||||
|
||||
PerfHelpers.record_result("string_key_lookup", scale, time_ms)
|
||||
|
||||
|
||||
## Test dictionary lookup performance with Script object keys
|
||||
func test_script_key_lookup(scale: int, test_parameters := [[1000], [10000], [100000]]):
|
||||
# Create script-based dictionary
|
||||
var script_dict: Dictionary = {}
|
||||
|
||||
# Populate with component scripts directly
|
||||
var component_types = [C_TestA, C_TestB, C_TestC, C_TestD]
|
||||
for comp_type in component_types:
|
||||
script_dict[comp_type] = []
|
||||
for i in scale / 4:
|
||||
script_dict[comp_type].append(i)
|
||||
|
||||
# Time lookups
|
||||
var time_ms = PerfHelpers.time_it(func():
|
||||
for i in 10000: # Many lookups
|
||||
var comp_type = component_types[i % 4]
|
||||
var _result = script_dict.get(comp_type, [])
|
||||
)
|
||||
|
||||
PerfHelpers.record_result("script_key_lookup", scale, time_ms)
|
||||
|
||||
|
||||
## Test dictionary insertion performance with String keys
|
||||
func test_string_key_insertion(scale: int, test_parameters := [[1000], [10000], [100000]]):
|
||||
var component_types = [C_TestA, C_TestB, C_TestC, C_TestD]
|
||||
|
||||
var time_ms = PerfHelpers.time_it(func():
|
||||
var string_dict: Dictionary = {}
|
||||
for i in scale:
|
||||
var comp_type = component_types[i % 4]
|
||||
var path = comp_type.resource_path
|
||||
if not string_dict.has(path):
|
||||
string_dict[path] = []
|
||||
string_dict[path].append(i)
|
||||
)
|
||||
|
||||
PerfHelpers.record_result("string_key_insertion", scale, time_ms)
|
||||
|
||||
|
||||
## Test dictionary insertion performance with Script object keys
|
||||
func test_script_key_insertion(scale: int, test_parameters := [[1000], [10000], [100000]]):
|
||||
var component_types = [C_TestA, C_TestB, C_TestC, C_TestD]
|
||||
|
||||
var time_ms = PerfHelpers.time_it(func():
|
||||
var script_dict: Dictionary = {}
|
||||
for i in scale:
|
||||
var comp_type = component_types[i % 4]
|
||||
if not script_dict.has(comp_type):
|
||||
script_dict[comp_type] = []
|
||||
script_dict[comp_type].append(i)
|
||||
)
|
||||
|
||||
PerfHelpers.record_result("script_key_insertion", scale, time_ms)
|
||||
|
||||
|
||||
## Test hash computation overhead - String path generation
|
||||
func test_get_resource_path_overhead(scale: int, test_parameters := [[10000], [100000], [1000000]]):
|
||||
var component_types = [C_TestA, C_TestB, C_TestC, C_TestD]
|
||||
|
||||
var time_ms = PerfHelpers.time_it(func():
|
||||
for i in scale:
|
||||
var comp_type = component_types[i % 4]
|
||||
var _path = comp_type.resource_path
|
||||
)
|
||||
|
||||
PerfHelpers.record_result("get_resource_path_overhead", scale, time_ms)
|
||||
|
||||
|
||||
## Test dictionary lookup performance with Integer keys
|
||||
func test_integer_key_lookup(scale: int, test_parameters := [[1000], [10000], [100000]]):
|
||||
# Create integer-based dictionary
|
||||
var int_dict: Dictionary = {}
|
||||
|
||||
# Populate with integer keys (simulating instance IDs or hashes)
|
||||
var component_types = [C_TestA, C_TestB, C_TestC, C_TestD]
|
||||
for i in range(4):
|
||||
int_dict[i] = []
|
||||
for j in scale / 4:
|
||||
int_dict[i].append(j)
|
||||
|
||||
# Time lookups
|
||||
var time_ms = PerfHelpers.time_it(func():
|
||||
for i in 10000: # Many lookups
|
||||
var key = i % 4
|
||||
var _result = int_dict.get(key, [])
|
||||
)
|
||||
|
||||
PerfHelpers.record_result("integer_key_lookup", scale, time_ms)
|
||||
|
||||
|
||||
## Test dictionary insertion performance with Integer keys
|
||||
func test_integer_key_insertion(scale: int, test_parameters := [[1000], [10000], [100000]]):
|
||||
var time_ms = PerfHelpers.time_it(func():
|
||||
var int_dict: Dictionary = {}
|
||||
for i in scale:
|
||||
var key = i % 4
|
||||
if not int_dict.has(key):
|
||||
int_dict[key] = []
|
||||
int_dict[key].append(i)
|
||||
)
|
||||
|
||||
PerfHelpers.record_result("integer_key_insertion", scale, time_ms)
|
||||
|
||||
|
||||
## Test Script.get_instance_id() overhead
|
||||
func test_get_instance_id_overhead(scale: int, test_parameters := [[10000], [100000], [1000000]]):
|
||||
var component_types = [C_TestA, C_TestB, C_TestC, C_TestD]
|
||||
|
||||
var time_ms = PerfHelpers.time_it(func():
|
||||
for i in scale:
|
||||
var comp_type = component_types[i % 4]
|
||||
var _id = comp_type.get_instance_id()
|
||||
)
|
||||
|
||||
PerfHelpers.record_result("get_instance_id_overhead", scale, time_ms)
|
||||
|
||||
|
||||
## Test realistic query performance with String keys (current implementation)
|
||||
func test_realistic_query_with_strings(scale: int, test_parameters := [[100], [1000], [10000]]):
|
||||
# Setup entities
|
||||
for i in scale:
|
||||
var entity = Entity.new()
|
||||
entity.name = "Entity_%d" % i
|
||||
if i % 2 == 0:
|
||||
entity.add_component(C_TestA.new())
|
||||
if i % 3 == 0:
|
||||
entity.add_component(C_TestB.new())
|
||||
world.add_entity(entity, null, false)
|
||||
|
||||
# Time queries (current string-based approach)
|
||||
var time_ms = PerfHelpers.time_it(func():
|
||||
for i in 100: # Execute query 100 times
|
||||
var _entities = world.query.with_all([C_TestA]).execute()
|
||||
)
|
||||
|
||||
PerfHelpers.record_result("realistic_query_with_strings", scale, time_ms)
|
||||
world.purge(false)
|
||||
Reference in New Issue
Block a user