garrysmod icon indicating copy to clipboard operation
garrysmod copied to clipboard

Optimizing the PlayerSelectSpawn

Open Vitroze opened this issue 5 months ago • 4 comments

I've modified the PlayerSelectSpawn to reduce execution time. In fact, this function is very time-consuming for a simple algorithm.

I've added the GM:PostCleanupMap() function to this pull request, so if I need to make another pull request, let me know ;)

Benchmark

You can see below the different tests carried out on other maps. During these tests, GM.SpawnPoints has already been created

The modified function will be named PlayerSelectSpawnNew during this benchmark.

Here's how the benchmark was carried out

local GAMEMODE = GAMEMODE or GM

local iStartSysTime = SysTime()
local iRepetition = 100000

for i = 1, iRepetition do
    GAMEMODE:PlayerSelectSpawnNew(Entity(1))
end

print("PlayerSelectSpawnNew took " .. (SysTime() - iStartSysTime) .. " seconds for " .. iRepetition .. " repetitions. It has " .. #GAMEMODE.SpawnPoints .. " spawn points.")
iStartSysTime = SysTime()
for i = 1, iRepetition do
    GAMEMODE:PlayerSelectSpawn(Entity(1)) 
end
print("PlayerSelectSpawn took " .. (SysTime() - iStartSysTime) .. " seconds for " .. iRepetition .. " repetitions. It has " .. #GAMEMODE.SpawnPoints .. " spawn points.")

gm_construct

PlayerSelectSpawnNew took 0.4067485999999 seconds for 100000 repetitions. It has 33 spawn points.
PlayerSelectSpawn took 1.2396119999999 seconds for 100000 repetitions. It has 33 spawn points.

We have a performance increase of 75.259762118433%.

gm_flatgrass

PlayerSelectSpawnNew took 0.26980260000001 seconds for 100000 repetitions. It has 56 spawn points.
PlayerSelectSpawn took 1.2598727 seconds for 100000 repetitions. It has 56 spawn points.

We have a performance increase of 82.264703033587%.

Vitroze avatar Jun 27 '25 00:06 Vitroze

Raaah, again some micro-optimization my dear Vitroze....

ah-shit-here-we-go-again

(we love it 💕)

DynamoRed avatar Jun 27 '25 00:06 DynamoRed

What about doing 1 loop over ents.GetAll() or ents.Iterator and check the classname of each entity, instead of doing 20 FindByClass calls?

robotboy655 avatar Jun 27 '25 01:06 robotboy655

What about doing 1 loop over ents.GetAll() or ents.Iterator and check the classname of each entity, instead of doing 20 FindByClass calls?

https://github.com/Facepunch/garrysmod/pull/2295 solves this

callumok2004 avatar Jun 27 '25 05:06 callumok2004

What about doing 1 loop over ents.GetAll() or ents.Iterator and check the classname of each entity, instead of doing 20 FindByClass calls?

That's right, I'm going to change that - thanks for the comment!

Vitroze avatar Jun 27 '25 10:06 Vitroze