Source.Python
Source.Python copied to clipboard
Improve TypeManager.function/TypeManager.virtual_function fetch speed by using cache.
Entity has a mechanism to speed up the retrieval of dynamic_attributes/server_classes, but TypeManager itself does not. With this improvement, instances created by TypeManager can speed up the retrieval of function/virtual_function.
In virtual_function, I tried to improve the performance by using type_info and caching, but it did not improve the performance.
Test Code (CS:GO/Linux):
import time
from memory import find_binary
from memory import make_object
from memory.manager import CustomType
from memory.manager import TypeManager
""" TypeManager.function Test"""
# _ZN9CCSPlayer12RoundRespawnEv
signature = b"\x55\x89\xE5\x56\x53\x83\xEC\x1C\x8B\x5D\x08\xFF\x35\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4\x10\x84\xC0\x0F\x85\x2A\x2A\x2A\x2A\x8B\x13"
# Cache signature
find_binary("server", srv_check=False)[signature]
manager = TypeManager()
class Test(CustomType, metaclass=manager):
_binary = "server"
_srv_check = False
_size = 0
_spawn = manager.function(signature)
# Cache function
Test._spawn
s = time.perf_counter()
for i in range(100000):
Test._spawn
e = time.perf_counter()
print(e-s, "Test._spawn")
# Cache function
test = Test()
test._spawn
s = time.perf_counter()
for i in range(100000):
test._spawn
e = time.perf_counter()
print(e-s, "test._spawn")
l = [Test() for i in range(100000)]
s = time.perf_counter()
for i in range(100000):
l[i]._spawn
e = time.perf_counter()
print(e-s, "Test()._spawn")
""" TypeManager.virtual_function Test"""
manager = TypeManager()
class Test(CustomType, metaclass=manager):
blind = manager.virtual_function(551, (DataType.FLOAT, DataType.FLOAT, DataType.FLOAT))
pointer = Entity.find("player").pointer
test = make_object(Test, pointer)
test.blind
s = time.perf_counter()
for i in range(100000):
test.blind
e = time.perf_counter()
print(e-s, "test.blind")
l = [make_object(Test, pointer) for i in range(100000)]
s = time.perf_counter()
for i in range(100000):
l[i].blind
e = time.perf_counter()
print(e-s, "make_object(Test, pointer).blind")
Since the implementation has changed, the test results have also changed. Output :
TypeManager.function Test
4.355441149324179 Test._spawn
4.830625455826521 test._spawn
4.801660872995853 Test()._spawn
↓
OLD: 0.02216128632426262 Test._spawn
OLD: 0.008792959153652191 test._spawn
OLD: 0.2989997826516628 Test()._spawn
NEW: 0.023133378475904465 Test._spawn
NEW: 0.29126785323023796 test._spawn
NEW: 0.293557733297348 Test()._spaw
TypeManager.virtual_function Test
0.5497394129633904 test.blind
0.5683586820960045 make_object(Test, pointer).blind
↓
OLD: 0.008566077798604965 test.blind
OLD: 0.5120681896805763 make_object(Test, pointer).blind
NEW: 0.46108797565102577 test.blind
NEW: 0.4727563001215458 make_object(Test, pointer).blind