Alternatives to nested if statements?

Lets say you have an if-elseif-elseif-else statement, where else is the outcome the majority of the time:

if a then
	funcA()
elseif b then
	funcB()
elseif c then
	funcC()
elseif d then
	funcD()
else
	funcE() -- outcome majority of time
end

This seems quite inefficient and messy. Can this be approached in a more efficient manner?

1 Like

Testing


I really hate using nested if statements sometimes. I recently found this stupid method of mine, but ask anyone else if this actually cause performance impacts.

if a or b or c or d then
	local _ = a and funcA() or b and funcB() or c and funcC() or d and funcD()
else funcE()
end

I mean, I guess? You could get messier:

a and funcA() or b and funcB() or c and funcC() or d and funcD() or funcE()

Or you can flatten your functions into one that accept different parameters to work around the issue. It depends on what kind of circumstances you’re working with. I personally prefer adding parameters to my functions so I can determine what should be done based on a specific circumstance.

local function A(B)
    [return] somethingWithB()
end
2 Likes

A solution I came up with to a problem like this’s to use a dictionary. When a value’s entered, it would get the function and fire it. An example of this is the following;

local Funcs = {
     A = function()
          print('Hello')
     end;
     B = function()
          print('World')
     end;
     C = function()
          print('!')
     end;
}
...
local FuncToExecute = Funcs[Val]
if FuncToExecute then
     FuncToExecute()
end
7 Likes

There’s no alternative that sustains the same level of performance. Also, I don’t think you’re going to see much of a problem with your current code. It doesn’t take long to run a handful of if statements.

It’s possible that branch prediction takes care of this a little bit, but I’m not familiar enough with how that works to say for sure. This is a feature at the CPU level, and I’m not sure how the Lua VM ties in with all of that.

13 Likes

You could make it messier, but in reality there is no good solution to this other than making something else take the mess away.

Some things you could do:

  • Branch a single line using a and a() or b and b() ect.
  • Make a dictionary for each value, effectively transferring the mess
  • Loop through all possible values and compare them, effectively making a shorter if if else line.
  • Just keep it how it is; Easy to read

All of these ways would not have significant difference in performance. It is basically your choice on what looks better

4 Likes

This really is the best of doing it to be honest. There are ways to reduce the character or line count, but that will make the code messy and perform worse. Remember, less code is not the same as faster code.

Unfortunately, there is no other efficient method of doing that, unless you can somehow turn a, b, c, and d into PropertyTables with the functions built-in. Lua currently doesn’t have a switch statement.

1 Like

While the instruction cache probably sets in well in the VM, but since it’s virtualized code (at least in vanilla Lua) the branch predictor probably doesn’t affect it greatly. Even then these hardware optimizations are too low level to be noticeable in Lua.

@OP Control flow is usually much more efficient than things such as table lookups, at least on the smaller scope. It should also be noted that internally, and and or usually behave the exact same way as an if statement.

3 Likes