Isaac Saffold
Isaac Saffold

Reputation: 1185

Performance of ternary operator vs if-else statement

Is there a difference in performance between the if-else statement and the ternary operator in Python?

Upvotes: 8

Views: 6651

Answers (4)

Manoj
Manoj

Reputation: 347

Tested on couple of OS and found ternary performed slower than if else condition

import timeit

def ternary_even_odd(num):
    return 2 if num % 2 == 0 else 1
def if_else_even_odd(num):
    if num % 2 == 0:
        return 2
    else:
        return 1

# Run benchmark with different input sizes
input_sizes = [100, 1000, 10000, 100000]
for size in input_sizes:
    num_runs = 10000  # Adjust iterations based on your needs
    ternary_time = timeit.timeit(lambda: [ternary_even_odd(i) for i in range(size)], number=num_runs)
    if_else_time = timeit.timeit(lambda: [if_else_even_odd(i) for i in range(size)], number=num_runs)

    print(f"Input size: {size}, Ternary time: {ternary_time:.6f} seconds, If-else time: {if_else_time:.6f} seconds")

This code can be tested to check the performance.

Upvotes: 0

rautamiekka
rautamiekka

Reputation: 281

Here're my tests in IPython 7.2.0 (which has %timeit, a built-in timing method that makes it extremely easy to measure executions. By default it makes 7 runs and 100 million loops each, so the results should usually be valid) used by PyCharm 2018.3.4 Community Edition x64, running CPython 3.7.2 x64. The OS is Window$ 10.0.17134 Enterprise x64:

##The 1st 2 are without quoting the statement to see how it affects the test.
%timeit 3 if True else 8
14.7 ns ± 0.319 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

%timeit 3 if False else 8
18.1 ns ± 0.211 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

##----------------------------------------------------------------------------

%timeit 'if True:\n    3\nelse:\n    8'
8.67 ns ± 0.314 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

%timeit 'if False:\n    3\nelse:\n    8'
8.4 ns ± 0.0598 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

##----------------------------------------------------------------------------

##The last 2 are with quoting the statement.
%timeit '3 if True else 8'
8.73 ns ± 0.256 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

%timeit '3 if False else 8'
9.37 ns ± 0.215 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

I think the numbers speak for the statements. A shame really, cuz I love the ternary op.

However, the ternary op's still absolutely useful, especially in the cases where covering all the possibilities in function call params would create a massive repeating of code, which I absolutely hate.

Upvotes: 2

timotree
timotree

Reputation: 1473

From some testing on Python 3.6.1, it seems like the full statement is faster.

My Results:

>>> timeit.timeit("""3 if True else 8""")
0.012174860001323395
>>> timeit.timeit("""3 if False else 8""")
0.019092951000857283
>>> timeit.timeit("""if True:
...     3
... else:
...     8""")
0.009110345999943092
>>> timeit.timeit("""if False:
...     3
... else:
...     8""")
0.00877297099941643

Upvotes: 0

Ned Batchelder
Ned Batchelder

Reputation: 376002

I doubt there is a performance difference. They compile to equivalent sequences of bytecodes:

>>> def f():
...   return a if b else c
...
>>> dis.dis(f)
  2           0 LOAD_GLOBAL              0 (b)
              2 POP_JUMP_IF_FALSE        8
              4 LOAD_GLOBAL              1 (a)
              6 RETURN_VALUE
        >>    8 LOAD_GLOBAL              2 (c)
             10 RETURN_VALUE
>>> def g():
...   if b:
...     return a
...   else:
...     return c
...
>>> dis.dis(g)
  2           0 LOAD_GLOBAL              0 (b)
              2 POP_JUMP_IF_FALSE        8

  3           4 LOAD_GLOBAL              1 (a)
              6 RETURN_VALUE

  5     >>    8 LOAD_GLOBAL              2 (c)
             10 RETURN_VALUE
             12 LOAD_CONST               0 (None)
             14 RETURN_VALUE

As with most performance questions, the answer is to measure.

Upvotes: 15

Related Questions