Why is [ ] faster than list( ) in python?
Which one do you prefer to create lists in Python? You will be surprised to know they don't work exactly the same.
First of all, we will compare the performance of creating a list using the brackets directly versus using list() constructor.
Lets compare the time to create an empty list. We use the magic command %timeit , this executes the setup statement once, and then returns the time it takes to execute the main statement a number of times, measured in seconds as a float. The argument is the number of times through the loop, defaulting to one million.
To create an empty list, []
runs more than three times faster than list()
, and if I am creating a list with some content?
Because []
is a literal syntax. Python can create bytecode just to create the list. We will use the dis
module. It supports the analysis of CPython bytecode by disassembling it.
As we can see at the picture above, the name list() is a separed variable and need to be resolved, the stack has to be involved to push the arguments, the frame has to be stored to retrieve later, and a call has to be made. That all takes more time.
For the empty case, that means you have at the very least a LOAD_NAME
(which has to search through the global namespace as well as the builtins
module) followed by a CALL_FUNCTION
, which has to preserve the current frame.
The case with numerical content, the disasembler is pretty similar:
We can see that the bytecodes of the two methods are completely different. That must be the reason why the performance is different.
When we use []
, the bytecode shows that there are only two steps.
BUILD_LIST
— Build a Python ListRETURN_VALUE
— Return the value
Very simple, right? When the Python interpreter sees the expression []
it just knows that it needs to build a list. So, it is very straightfoward.
How about list()
?
LOAD_NAME
— Try to find the object “list” into all scope variablesCALL_FUNCTION
— Call the “list” function to build the Python ListRETURN_VALUE
— Return the value
Every time we use something with a name, the Python interpreter will search the name in the existing variables scopes. It searchs considering an order such as Local Scope -> Enclosing Scope -> Global Scope -> Built-in Scope.
This search will definitely need some time.
The same thing happens when you use the construct dict() versus {} (an empty dict). Some people says that []
and {}
are the most pythonic and readable ways to create empty lists/dicts. However, be carefull when using {} to create a dictionary with content:
this_is_a_set = {5}
this_is_a_dict = {}
The first one creates a set with one element, the second creates an empty dict and not a set.
Now you know. Prefere using [] instead of list() in your code.
For content in portuguese @aprendadatascience or https://aprendadatascience.com