Efficiency of hook.Call?

How efficient is hook.Call? I’d like to use it for cross-addon logging and messaging (so I can format all logs to a similar syntax) (e.g. hook.Call(“log”, gmod.GetGamemode(), “Hello, world”)). Is this a good idea, or would it be too slow with lots of messages?

Instead of gmod.GetGamemode, use GAMEMODE - needs to be the GAMEMODE table to access GM functions. Alternatively it can be nil to access Standard functions, or a different table to access other table functions.

or use hook.Run

Ah, that’s the one I’m looking for. Thanks!

Will this have any significant performance hits if called, say, 10 times a second?

Probably not. If you have a billion hooks or if the hooks themselves are expensive, yes.

None.

I feel like this would depend on what your function was doing 10 times a second. There are hooks like Think and Tick that you can use to be called frequently, but I wouldn’t put a demanding function together with that.

EDIT: We all kinda posted at the same time, but like Willox said.

https://dl.dropboxusercontent.com/u/26074909/tutoring/_utilities/util_benchmark.lua

] dev_bechload
Total Process Time is how long the benchmark took to complete.
Total Operation Time is the SUM of how long the individual function calls took.
Average Operation Time is the AVERAGE time to execute the function.

Total Benchmark Process Time: 0.00043590772889956 seconds to run 1000 times
Total Operation Time: 0.00028819290287174 seconds
Avg. Operation Time: 2.8819290287174e-007 seconds


concommand.Add( "dev_bechload", function( _p, _cmd, _args )
	util.Benchmark( 1000, function( )
		hook.Call( "PlayerLoadout", GAMEMODE, Entity( 1 ) );
	end );
end );

] dev_benchload
Total Process Time is how long the benchmark took to complete.
Total Operation Time is the SUM of how long the individual function calls took.
Average Operation Time is the AVERAGE time to execute the function.

Total Benchmark Process Time: 0.42223495511729 seconds to run 1000000 times
Total Operation Time: 0.28268701356512 seconds
Avg. Operation Time: 2.8268701356512e-007 seconds


concommand.Add( "dev_benchload", function( _p, _cmd, _args )
	util.Benchmark( 1000000, function( )
		hook.Call( "PlayerLoadout", GAMEMODE, Entity( 1 ) );
	end );
end );

notice exponential -007

That was running PlayerLoadout too. Using hook.Call is very cheap. If you are going to use NWVars and call them 10 times per tick, or so, I’d say do something like caching the value: https://dl.dropboxusercontent.com/u/26074909/tutoring/_systems/player_color_based_on_rank.lua.html

https://dl.dropboxusercontent.com/u/26074909/tutoring/making_players_invisible_and_caching_variables.lua.html

etc…

Wow, I didn’t think hook.Call was that fast. Thanks!

Things you want to be careful on are the obvious ( or less than obvious ) things such as NWVars as described by the edit in the post above, and in hooks like HUDShouldDraw…

https://dl.dropboxusercontent.com/u/26074909/tutoring/benchmarking_tips/benchmarking_hud_stuff.lua.html

15 seconds vs 0.08 seconds… Both use a table, the difference is the table.HasValue approach best case is O( 1 ), worst-case is O( n ), and it is likely that it is O( n )… But, the other one directly accesses the value.

https://dl.dropboxusercontent.com/u/26074909/tutoring/vgui/proper_hud_creation.lua.html

Make sure you design your structs in such a way that makes things easy to find. IF you can’t get around it, make a map table which references the other point but with a different set of data…