За последнее время я наблюдал довольно много странностей, когда играл с timeit и показателями Python в последнее время.
Во-первых, зная, что math.sin (1) == (e ** 1j).имаг, мне было интересно узнать их относительные скорости.Вот что я нашел:
>>> timeit('sin(1)', 'from math import sin')
0.12068345113220857
>>> timeit('(e**1j).imag', 'from math import e')
0.27201285586511403
>>> timeit('exp(1j).imag', 'from cmath import exp')
0.25259275173584683
>>> timeit('(2.718281828459045**1j).imag')
0.04272853350335026
Это странно для меня.Почему использование самого номера и **
намного быстрее, чем что-либо еще?Почему это быстрее, чем грех?Я знаю, что это не из-за импорта;Я исключил это по отдельности.Также рассмотрим:
>>> (2.718281828459045**1j).imag
0.8414709848078965
>>> sin(1)
0.8414709848078965
Итак, он дает правильные ответы.
Я решил покопаться немного глубже и обнаружил, что .imag - настоящий виновник медлительности (2.718281828459045**1j).imag
.На самом деле,
>>> timeit('2.718281828459045**1j')
0.013987474140321865
Кажется, это не что-то конкретное для 1j;Я могу использовать 2j или 0,95j и получить ту же скорость.Кроме того, это даже так быстро, как сложное и регулярное умножение!
>>> timeit('1*1j')
0.01617102287718808
>>> timeit('1*1')
0.016536898499907693
Я полностью сбит с толку.Как это может быть намного быстрее, чем грех, когда он выполняет как минимум столько же работы (а также вычисляет cos)?Как это может быть так быстро, как целочисленное умножение?Я подозреваю, что отчасти это происходит из-за шума из-за накладных расходов времени (где-то должен быть цикл), но даже это не все объясняет.Буду признателен за любую помощь с пониманием.