Why is ternary operator two times faster than if statement?


#1
function with_ternary()
  sum(x%3==0 || x%5==0 ? x : 0 for x=1:999999999)
end

function with_if()
  sum(x for x=1:999999999 if x%3 == 0 || x%5 == 0)
end

I call @time with_if() and @time with_ternary() several times after that to make sure it’s already compiled. The results show me that with_ternary() funcition is 2 times faster than with_if() function. Can someone explain to why is that the case?

I know that two functions are not exactly the same because with_ternary() is passing zeros to the sum() function. So why is it so much faster?

@time with_ternary()
233333333166666668
2.206624 seconds (7 allocations: 240 bytes)
@time with_if()
233333333166666668
4.835853 seconds (12 allocations: 416 bytes)

#2

The two functions are not equivalent the equivalent to the ternary operator version is

julia> function with_if2()
         sum(if x%3 == 0 || x%5 == 0 x else 0 end for x=1:999999999)
       end

Which should give you similar performance.


#3

Does this mean that conditional generator expressions are slow?


#4

Thank you yuyichao. Function with_if2() that you proposed gives same performance as with_ternary().

But why expression without “else” is 2 times slower

 sum(x for x=1:999999999 if x%3 == 0 || x%5 == 0)

in comparison to the ternary syntax

sum(if x%3 == 0 || x%5 == 0 x else 0 end for x=1:999999999)

I want to understand how things work underneath to write functions in an optimal way


#5

Going though a filter iterator will be a little slower.