garrysmod icon indicating copy to clipboard operation
garrysmod copied to clipboard

Move player.GetAll to lua

Open aStonePenguin opened this issue 6 months ago • 13 comments

It's significantly faster to create the table in lua than it is to push it from C.

Benhmarks:

With 1 player:

old
0.13022569999885
new
0.0056074999993143

With 128 players:

old
1.1069849000014
new
0.29961660000117
function player.GetAll2()
	local players = {}

	for _, pl in player.Iterator() do
		table.insert(players, pl)
	end

	return players
end

print 'old'
local s = SysTime()

for i = 1, 100000 do
	player.GetAll()
end

print(SysTime() - s)

print 'new'
s = SysTime()
for i = 1, 100000 do
	player.GetAll2()
end

print(SysTime() - s)

aStonePenguin avatar Jun 06 '25 19:06 aStonePenguin

Hello, You might as well use the player.Iterator to avoid making a loop for nothing.

Vitroze avatar Jun 06 '25 20:06 Vitroze

Hello, You might as well use the player.Iterator to avoid making a loop for nothing.

The table returned by player.Iterator is meant to be read-only (per the documentation wiki). Copying it into a fresh table protects it.

Malivil avatar Jun 06 '25 20:06 Malivil

This can't be done until the hook library has priorities, addons can call player.GetAll in EntityRemoved or OnEntityCreated hooks

Astralcircle avatar Jun 07 '25 03:06 Astralcircle

This can't be done until the hook library has priorities, addons can call player.GetAll in EntityRemoved or OnEntityCreated hooks

Yes this is correct, I don't use player.Iterator because it's not safe. We need priorities AND protected calls for this to work properly.

Srlion avatar Jun 08 '25 17:06 Srlion

This can't be done until the hook library has priorities, addons can call player.GetAll in EntityRemoved or OnEntityCreated hooks

Yes this is correct, I don't use player.Iterator because it's not safe. We need priorities AND protected calls for this to work properly.

Personally I use it calmly just thanks to your hook library + PRE_HOOK

Astralcircle avatar Jun 08 '25 17:06 Astralcircle

Wait, how can luajit be way faster than compiled code? Is the C code causing reallocations because it's not using https://www.lua.org/manual/5.1/manual.html#lua_createtable with supplying the size or is it doing something so stupid? The calling of a C function shouldn't be too slow? @robotboy655 could you confirm?

Srlion avatar Jun 09 '25 03:06 Srlion

It does in fact use lua_createtable with provided pre-allocation size. I guess the slowdown comes from using the internal wrappers for Lua stuff, as well as perhaps some extra stuff the function does.

image

Removing the internal wrappers and some other unnecessary code, these are the results (new3 is a modified C function, new2 is the code above, 127 bots)

robotboy655 avatar Jun 09 '25 15:06 robotboy655

I guess ents.GetAll can benefit from same stuff and have like 2000x performance improvement? lol

Srlion avatar Jun 09 '25 15:06 Srlion

Not 2000x, but seems to be around 2x.

image

robotboy655 avatar Jun 09 '25 16:06 robotboy655

That number is so huge really, considering lots of servers have like 2k+ entities lol

Srlion avatar Jun 09 '25 16:06 Srlion

I guess ents.GetAll can benefit from same stuff and have like 2000x performance improvement? lol

If https://github.com/Facepunch/garrysmod-issues/issues/5800 ever gets solved.

aStonePenguin avatar Jun 09 '25 20:06 aStonePenguin

I guess ents.GetAll can benefit from same stuff and have like 2000x performance improvement? lol

If Facepunch/garrysmod-issues#5800 ever gets solved.

This is unaffected by this

Astralcircle avatar Jun 10 '25 06:06 Astralcircle

The benchmark needs retesting when recent changes on dev beta.

robotboy655 avatar Jun 25 '25 17:06 robotboy655