Подтвердить что ты не робот

Список Python() против скорости построения списка

Это интересно; list(), чтобы заставить итератор получить фактический список, намного быстрее, чем [x for x in someList] (понимание).

Является ли это реальным или мой тест слишком прост? Ниже приведен код:

import time    

timer = time.clock()
for i in xrange(90):

    #localList = [x for x in xrange(1000000)]   #Very slow, took me 6.8s
    localList = list(xrange(1000000))           #Very fast, took me 0.9s

    print localList[999999] #make sure list is really evaluated.

print "Total time: ", time.clock() - timer
4b9b3361

Ответ 1

Понимание списка выполняет цикл в байт-коде Python, как обычный цикл for.

Вызов list() выполняет итерацию целиком в коде C, который намного быстрее.

Байт-код для понимания списка выглядит следующим образом:

>>> import dis
>>> dis.dis(compile("[x for x in xrange(1000000)]", '<stdin>', 'exec'))
  1           0 BUILD_LIST               0
              3 LOAD_NAME                0 (xrange)
              6 LOAD_CONST               0 (1000000)
              9 CALL_FUNCTION            1
             12 GET_ITER            
        >>   13 FOR_ITER                12 (to 28)
             16 STORE_NAME               1 (x)
             19 LOAD_NAME                1 (x)
             22 LIST_APPEND              2
             25 JUMP_ABSOLUTE           13
        >>   28 POP_TOP             
             29 LOAD_CONST               1 (None)
             32 RETURN_VALUE        

Указатели >> грубо дают вам границы цикла, который выполняется, поэтому у вас есть 1 миллион шагов STORE_NAME, LOAD_NAME и LIST_APPEND для выполнения в цикле оценки байт-кода Python.

list(), с другой стороны, просто захватывает значения из xrange() итерации напрямую, используя C API для итерации объектов, и может использовать длину объекта xrange(), чтобы предварительно выделить объект списка чем расти динамически.