Почему для умножения массивов понимание списка намного быстрее, чем просто тупое?

Недавно я ответил наЭТОТ На вопрос, который требовал умножения 2 списков, какой-то пользователь предложил следующий способ, используя numpy, наряду с моим, который я считаю правильным:

(a.T*b).T

Также я обнаружил, чтоaray.resize() имеет такую ​​же производительность, как это. В любом случае, другой ответ предложил решение с использованием понимания списка:

[[m*n for n in second] for m, second in zip(b,a)]

Но после бенчмарка я увидел, что понимание списка выполняется очень быстро, а не просто:

from timeit import timeit

s1="""
a=[[2,3,5],[3,6,2],[1,3,2]]
b=[4,2,1]

[[m*n for n in second] for m, second in zip(b,a)]
"""
s2="""
a=np.array([[2,3,5],[3,6,2],[1,3,2]])
b=np.array([4,2,1])

(a.T*b).T
"""

print ' first: ' ,timeit(stmt=s1, number=1000000)
print 'second : ',timeit(stmt=s2, number=1000000,setup="import numpy as np")

результат:

 first:  1.49778485298
second :  7.43547797203

Как видите, NumPy примерно в 5 раз быстрее. но самое удивительное было то, что он быстрее без использования транспонирования и для следующего кода:

a=np.array([[2,3,5],[3,6,2],[1,3,2]])
b=np.array([[4],[2],[1]])

a*b 

Понимание списка все еще было в 5 раз быстрее. Так что кроме этого пункта, что понимание списка выполняется в C, здесь мы использовали 2 вложенных цикла иzip функция Так в чем может быть причина? Это из-за операции* в нуди?

Также обратите внимание, что нет проблем сtimeit здесь я положилimport участие вsetup.

Я также попробовал это с большими массивами, разница становится меньше, но все равно не имеет смысла:

s1="""
a=[[2,3,5],[3,6,2],[1,3,2]]*10000
b=[4,2,1]*10000

[[m*n for n in second] for m, second in zip(b,a)]
"""
s2="""
a=np.array([[2,3,5],[3,6,2],[1,3,2]]*10000)
b=np.array([4,2,1]*10000)

(a.T*b).T

"""



print ' first: ' ,timeit(stmt=s1, number=1000)
print 'second : ',timeit(stmt=s2, number=1000,setup="import numpy as np")

результат:

 first:  10.7480301857
second :  13.1278889179

Ответы на вопрос(1)

Ваш ответ на вопрос