Home > Enterprise >  Is there a more optimal way to loop through this list?
Is there a more optimal way to loop through this list?

Time:09-21

I have declared a list of fruits like:

def fruits = ["apple", "orange", "pineapple"]

and I use the list like

for (fruit in fruits){
    if(fruit=="orange"){
      println("A delicious ${fruit}")
    }
    if(fruit=="pineapple"){ 
      println("Another delicious ${fruit}")
    }
    if(fruit=="apple"){ 
      println("More delicious ${fruit}"})
    }
}

This works. But I'm just curious to see if there is a better to achieve the same result.

Thanks for your help.

CodePudding user response:

Usually, for such problems, you'd have two ways to go about it. I'm using Python here as an example to explain the difference in syntax and the results it might generate for you.

for i in range(len(fruits)):

or the one which you've used

for fruit in fruits:

Analysing the bytecode

[Alternate Solution]

 12       0 SETUP_LOOP              40 (to 43)
          3 LOAD_GLOBAL              0 (range)
          6 LOAD_GLOBAL              1 (len)
          9 LOAD_FAST                0 (fruits)
         12 CALL_FUNCTION            1
         15 CALL_FUNCTION            1
         18 GET_ITER            
    >>   19 FOR_ITER                20 (to 42)
         22 STORE_FAST               1 (i)

13       25 LOAD_GLOBAL              2 (print)
         28 LOAD_FAST                0 (fruits)
         31 LOAD_FAST                1 (i)
         34 BINARY_SUBSCR       
         35 CALL_FUNCTION            1
         38 POP_TOP             
         39 JUMP_ABSOLUTE           19
    >>   42 POP_BLOCK           
    >>   43 LOAD_CONST               0 (None)
         46 RETURN_VALUE      

[Your Solution]

17        0 SETUP_LOOP              24 (to 27)
          3 LOAD_FAST                0 (fruits)
          6 GET_ITER            
    >>    7 FOR_ITER                16 (to 26)
         10 STORE_FAST               1 (fruit)

18       13 LOAD_GLOBAL              0 (print)
         16 LOAD_FAST                1 (fruit)
         19 CALL_FUNCTION            1
         22 POP_TOP             
         23 JUMP_ABSOLUTE            7
    >>   26 POP_BLOCK           
    >>   27 LOAD_CONST               0 (None)
         30 RETURN_VALUE

This makes it very clear that your solution is far more optimized when it comes to the loop itself. However, this problem with your block is that you're using if statements everywhere, this means that each and every statement will be evaluated and checked even tho the loop has already found the value you were looking for.

A much better way would be to use if-else instead to further make it more optimized. However instead of using nested if statements a better faster and cleaner would be to replace them completely with a switch statement as long as the number of cases are good.

CodePudding user response:

Think that with every if-statement the complexity of a program increases, better avoid them as much as possible and also avoid switch-statements which are even worse.

Your code is efficient but ugly, because it cannot scale well. If you modify the list, then you need to modify the loop as well. With a modern language as groovy, you can write this (as already suggested):

def fruits = [
    apple : { "A delicious $it" }, 
    orange : { "Another delicious $it" },
    pineapple : { "More delicious $it" }
]

fruits.each { fruit, action ->
    println action(fruit)
}

This can be inefficient comparing with your code, because it involves a map, but if I would care about the speed I would go for another programming language.

  • Related