Here you compare apples and pears. One method performs a simple assignment, the other calls a function. Yes, function calls will add overhead.
You should disable this to the minimum minimum for timeit :
>>> import timeit >>> timeit.timeit('a = 5') 0.03456282615661621 >>> timeit.timeit('foo()', 'def foo(): a = 5') 0.14389896392822266
Now all we have done is add a function call ( foo does the same), so you can measure the extra time that the function calls. You cannot argue that it is almost 4 times slower, no, calling a function adds 0.11 seconds overhead for 1,000,000 iterations.
If instead of a = 5 we do something that takes 0.5 seconds to complete a million iterations, moving them to a function will not force you to take 2 seconds. Now it will take 0.61 seconds, because the function overhead is not growing.
A function call should handle the stack by clicking on it with a local frame, creating a new frame, and then clearing it again when the function returns.
In other words, moving operators to a function adds a little overhead, and the more operators you switch to this function, the less overhead becomes a percentage of the total work done. A function never makes these statements slower.
A Python function is just an object stored in a variable; you can assign functions to another variable, replace them with something completely different, or delete them at any time. When you call a function, you first refer to the name by which they are stored ( foo ), and then call the function object ( (arguments) ); this search must occur every time in a dynamic language.
You can see this in the bytecode generated for the function:
>>> def foo(): ... pass ... >>> def bar(): ... return foo() ... >>> import dis >>> dis.dis(bar) 2 0 LOAD_GLOBAL 0 (foo) 3 CALL_FUNCTION 0 6 RETURN_VALUE
The operation code LOAD_GLOBAL looks at the name ( foo ) in the global namespace (basically, searching in a hash table) and pushes the result onto the stack. CALL_FUNCTION then calls everything on the stack, replacing it with the return value. RETURN_VALUE returned from the function call, again taking what is topmost on the stack as the return value.