Strange difference in time between add and extend two lists

Viewed 65

If I take two list, I can concatenate them with the + operator or with the .extend() method. Both do the same thing.

But if i do list1=list1+list2 it takes (in my case) near 0.048ms. Instead, if I do list1.extend(list2) it takes <0.001ms (also in my case).

Why so much difference if they do the same thing? What's the difference and when should I use the + if it's so much slower?

3 Answers

You want to compare two code segments together? dis module is your friend.

In [3]: dis.dis("l1=[1, 2, 3];l2=[4, 5, 6];l1=l1+l2")                                                                                                                                                       
  1           0 LOAD_CONST               0 (1)
              2 LOAD_CONST               1 (2)
              4 LOAD_CONST               2 (3)
              6 BUILD_LIST               3
              8 STORE_NAME               0 (l1)
             10 LOAD_CONST               3 (4)
             12 LOAD_CONST               4 (5)
             14 LOAD_CONST               5 (6)
             16 BUILD_LIST               3
             18 STORE_NAME               1 (l2)
             20 LOAD_NAME                0 (l1)
             22 LOAD_NAME                1 (l2)
             24 BINARY_ADD
             26 STORE_NAME               0 (l1)
             28 LOAD_CONST               6 (None)
             30 RETURN_VALUE

In [4]: dis.dis("l1=[1, 2, 3];l2=[4, 5, 6];l1.extend(l2)")                                                                                                                                                  
  1           0 LOAD_CONST               0 (1)
              2 LOAD_CONST               1 (2)
              4 LOAD_CONST               2 (3)
              6 BUILD_LIST               3
              8 STORE_NAME               0 (l1)
             10 LOAD_CONST               3 (4)
             12 LOAD_CONST               4 (5)
             14 LOAD_CONST               5 (6)
             16 BUILD_LIST               3
             18 STORE_NAME               1 (l2)
             20 LOAD_NAME                0 (l1)
             22 LOAD_METHOD              2 (extend)
             24 LOAD_NAME                1 (l2)
             26 CALL_METHOD              1
             28 POP_TOP
             30 LOAD_CONST               6 (None)
             32 RETURN_VALUE

In [5]:  

As yo can see, the difference here being between following segments from the first code:

         24 BINARY_ADD
         26 STORE_NAME 

and followings from the second:

         22 LOAD_METHOD              2 (extend)
         26 CALL_METHOD              1
         28 POP_TOP

All three instructions in second code are roughly as time consuming as the BINARY_ADD instruction from the first code. They are in fact doing a similar job, adding items from one list to another. But the extra STORE_NAME in first code is causing it to be slower because crating a new object and storing it in memory takes time.

enter image description here

This operation creates new list without affecting to any list:

list1=list1+list2

This operation does not create new one and change first one:

list1.extend(list2)

Compare second one with:

list1 += list2

They are not doing the same thing. Consider the following setup:

list1 = [1, 2, 3]
list2 = [4, 5]
list3 = list1

If you then run list1 = list1 + list2 or list1.extend(list2) then you get different values in list3

list1 = list1 + list2
print(list3)  # [1, 2, 3]
list1.extend(list2)
print(list3)  # [1, 2, 3, 4, 5]

This happens because operator + creates new object for list1, but extend modifies list in place and list3 points to the same object.

Related