Page 1 of 1
Variable check efficiency
Posted: Sun Sep 24, 2017 4:41 am
by robertpaulson
Hi. I can't find this information on the net, but if someone knows what variable type (Boolean, string, number) is most efficient for conditional checks?
in my mod i have to check for 3 certain conditions every second, which happens in "tick.event" so things are being executed every tick. right now i have:
Code: Select all
function process_tick()
current_tick = game.tick
if current_tick % 60 == 36 then
if boolean_toggle1== true then
....stuff here...
end
if boolean_toggle2 == true then
....stuff here...
end
if boolean_toggle3 == true then
....stuff here...
end
so it computes current_tick % 60 == 36 every tick and then 3 Booleans every second.... is it better to have 3 booleans checked every tick or leave it in the current state?
because if its ok right now I was thinking of replacing the 3booleans with one string or a number (the toggles control a sequence of events so they can't coexist, that way I can just use "status=1 or 2 or 3")
Re: Variable check efficiency
Posted: Thu Sep 28, 2017 4:24 am
by eradicator
IF and ONLY IF your cases are mutually exclusive and you want to overengineer your stuff you can try directly calling a function from a table of functions like this:
Code: Select all
local cases = {
[1] = function()
--dostuff1
end,
[2] = function()
--dostuff2
end,
[3] = function()
--dostuff3
end
}
script.on_event(defines.events.on_tick,function(event)
if event.tick % 60 == 36 then cases[YOUR_CASE_VARIABLE]() end
end)
Using a modulo on the current tick is indeed the correct method to do things not-every-tick - and MUCH faster than running all the checks every tick. The type of condition you check isn't going to affect performance in a relevant way. If you really care booleans are probably the fastest because of their simple data structure (there's just a 0 or 1 bit).
You don't however need to store the game tick in a variable, much less a global one like you did here:
A common approach would look more like this:
Code: Select all
script.on_event(defines.events.on_tick,function(event)
if event.tick % 60 ~= 36 return end
if bool1 == true then
--dostuff1
elseif int2 == "2" then
--dostuff2
elseif string3 == "three" then
--dostuff3
end
end)
Re: Variable check efficiency
Posted: Sun Oct 01, 2017 4:25 pm
by robertpaulson
eradicator wrote:
Using a modulo on the current tick is indeed the correct method to do things not-every-tick - and MUCH faster than running all the checks every tick. The type of condition you check isn't going to affect performance in a relevant way. If you really care booleans are probably the fastest because of their simple data structure (there's just a 0 or 1 bit).
I see, that was the part I was actually curious about. So to clarify this, running the modulo check every tick (I understand that the expression "if event.tick % 60 == 36 then" is evaluated every tick, unless there is some magic going on here) is better than checking for 3 Booleans?... The simple structure of the Boolean check is what I had in mind. It's just a check for 0/1 instead of evaluating a math expression and then comparing it... I understand this is probably semantics since it will not be noticeable at all, but from curiosity and maybe good programming practice it would be nice to know this... BTW that 1st snipped with storing functions in a table is sexy as hell
Edit: what I'm forgetting to mention is that the actual "stuff" will be happening every 60ticks anyway, its just an order of Booleans vs modulo (not dropping modulo all together- that would be a bad idea)... another thing worth mentioning is that the Booleans will be all false for majority of the time
Edit2: I just realized I'm probably overthinking this thing majorly....
Re: Variable check efficiency
Posted: Sun Oct 01, 2017 5:27 pm
by DaveMcW
robertpaulson wrote:running the modulo check is better than checking for 3 Booleans?... The simple structure of the Boolean check is what I had in mind.
That may be true on a hardware level, but by the time you get to the level of the Lua virtual machine there is so much overhead that you do better minimizing the number of checks.
And you are overthinking things, most of your mod performance will be tied up in API functions. Reducing the number (and size) of API calls is far more important.
Re: Variable check efficiency
Posted: Sun Oct 01, 2017 8:47 pm
by eradicator
robertpaulson wrote: So to clarify this, running the modulo check every tick (I understand that the expression "if event.tick % 60 == 36 then" is evaluated every tick [...]
Yes. That will run every tick. But that's - as i mentioned - basically what everybody does. Feel free to do performance measuring yourself tho. Using the log("sometext") command you can get a timestamp at execution time. So just put the stuff you want to measure in a loop and compare timestamps before and after the loop. But don't be sad when all you get is a difference of 2 nanoseconds

. Which is also about the difference i got by replacing game.tick with event.tick

. In your special case with exactly 3 bools using an if then else (not yours without else) sorted by frequency of occurance _might_ actually be those few nanoseconds faster. But then later when you forgot about this discussion and expand the mod you'll probably make it slower again by adding more checks.
robertpaulson wrote:BTW that 1st snipped with storing functions in a table is sexy as hell
Glad you liked it. As table lookups are amongst the cheapest operations lua offers it probably is a good solution for your problem of mutually exclusive conditions. Ofc you'd need to make sure that you don't try to use an empty index

.
robertpaulson wrote:Edit: what I'm forgetting to mention is that the actual "stuff" will be happening every 60ticks anyway, its just an order of Booleans vs modulo (not dropping modulo all together- that would be a bad idea)... another thing worth mentioning is that the Booleans will be all false for majority of the time
Are you implying you already have an "every 60 ticks" check somewhere else? Sounds like you're checking the same thing twice then?
robertpaulson wrote:Edit2: I just realized I'm probably overthinking this thing majorly....
Yes. Most definetly.

#PrematureOptimization
The greatest potential for optimization is indeed in reducing/proper usage of API calls like Dave mentioned above.