I’m just curious about which is the most efficient way of doing this kind of node enumiration:
for i in something():
o=[var1,var2,var3,varN][i]
o.new()
o.do_something_based_on_number_of_loops()
add_child(o)
or
for i in something():
match i:
0:
o=var1
o.new()
o.do_something_based_on_number_of_loops()
add_child(o)
1:
o=var2
o.new()
o.do_something_based_on_number_of_loops()
add_child(o)
2:
o=var3
o.new()
o.do_something_based_on_number_of_loops()
add_child(o)
N-1:
o=varN
o.new()
o.do_something_based_on_number_of_loops()
add_child(o)
or
var items = [var1,var2,var3,varN]
for i in something():
o=items[i]
o.new()
o.do_something_based_on_number_of_loops()
add_child(o)
Or is there a more efficient way of doing it?
Edit: Sorry if that wasn’t clear. Is it better to constantly get something from an “unstored list”, store the list in a variable, or not use a list and use a match statement instead? Do they have any advantages/disadvantages that make them better in certain situations?
Use:
items=[...] for o in items: ...
This is the most direct way of doing what you want. The first option might allocate a new array each iteration, which is unnecessary. The match statement is both a pain in the ass to write and less direct, which at best compiles to the same thing and at worst has you doing a bunch of totally unneeded comparisons.
If this ‘i’ variable you used isn’t just an incrementing counter, use the last option. If it is though, it’s an extra counter you don’t actually need.
The performance difference here would be so small I doubt you could even observe it. So, you really shouldn’t worry about this particular pattern. Compiler optimizations are more likely to trigger on simple, direct code, so writing it as directly as possible is probably the fastest option anyway.
- They don’t do the same thing so I’m assuming you’re trying to iterate over something like in n3
- n3 should theoretically be the fastest as there’s only one allocation and less branches
- Time it with
get_ticks_usec()
over a significant number of samples https://docs.godotengine.org/en/stable/classes/class_time.html#class-time-method-get-ticks-usec - None of this will matter because GDScript is interpreted and the execution times vary wildly based on how the moon is aligned
- Premature optimization, yada yada
For the first case, it’s probably better to use
Dictionary
instead of a match on an array, or matrix as you presented.var dictio = {"key":value, "key2":value2}
Unless you’re dealing with over 1k elements, any performance difference between Dict and Array might as well be a margin of error. https://docs.godotengine.org/en/stable/classes/class_dictionary.html
For that for you presented later, it should be
for i in items:
,i
then will point directly to the value in that position of the array.o = i
What you are doing, or attempting to, isn’t clear
At face value, none of those things are “apples to apples”, the first thing is a matrix or Vector2. The second is simply a match, which is “a series of if/elif”. Efficiency here comes mainly from the type of of the object being matched: bool is the fastest, int probably second, then float, then string. The third you’re just running through the array. All different things, each useful for a different purpose and none directly equivalent to another, thus it’s impossible to say which is the most efficient.
I might be wrong, but the 2nd case looks like an anti pattern, the loop switch sequence .
The last case looks the most readable to me. Always start with that unless there’s a clear reason not to (eg inefficient multiple nested loops).