Variable check efficiency

Place to get help with not working mods / modding interface.
Post Reply
robertpaulson
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Sun Jun 18, 2017 2:21 pm
Contact:

Variable check efficiency

Post 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")

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Variable check efficiency

Post 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:

Code: Select all

 current_tick = game.tick 
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)
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

robertpaulson
Long Handed Inserter
Long Handed Inserter
Posts: 92
Joined: Sun Jun 18, 2017 2:21 pm
Contact:

Re: Variable check efficiency

Post 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....

User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3700
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Variable check efficiency

Post 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.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Variable check efficiency

Post 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 :P. 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. :ugeek: #PrematureOptimization
The greatest potential for optimization is indeed in reducing/proper usage of API calls like Dave mentioned above.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

Post Reply

Return to “Modding help”