Search code examples
pythonperformanceoptimizationlocal-variables

Is splitting assignment into two lines still just as efficient?


From a runtime efficiency perspective in python are these equally efficient?

x = foo()
x = bar(x)

VS

x = bar(foo())

I have a more complex problem that can essentially be boiled down to this question: Obviously, from a code length perspective the second is more efficient, but is the runtime better as well? If they are not, why not?


Solution

  • Here's a comparison:

    First case:

    %%timeit
    def foo():
        return "foo"
    
    def bar(text):
        return text + "bar"
    
    def test():
        x = foo()
        y = bar(x)
        return y
    
    test()
    #Output:
    'foobar'
    529 ns ± 114 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

    Second case:

    %%timeit
    
    def foo():
        return "foo"
    
    def bar(text):
        return text + "bar"
    
    def test():   
        x = bar(foo())
        return x
    
    test()
    #Output:
    'foobar'
    447 ns ± 34.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

    But that is just the comparison running %%timeit once for each case. The following are times for 20 iterations(time in ns) for each case:

    df = pd.DataFrame({'First Case(time in ns)': [623,828,634,668,715,659,703,687,614,623,697,634,686,822,671,894,752,742,721,742], 
                   'Second Case(time in ns)': [901,786,686,670,677,683,685,638,628,670,695,657,698,707,726,796,868,703,609,852]})
    
    df.plot(kind='density', figsize=(8,8))
    

    enter image description here

    It was observed, with each iteration, the differences were diminishing. This plot shows that the performance difference isn't significant. From a readability perspective, the second case looks better.

    In the first case, two expressions are evaluated: the first expression assigns the return value from foo() to x first and then the second expression calls bar() on that value. This adds some overhead. In the second case only one expression is evaluated, calling both functions at once and returning the value.