Путаница при подсчете прошедшего времени в питоне? - PullRequest
2 голосов
/ 09 августа 2010

Итак, я хотел сравнить производительность Python между 2,6 и 3,1, поэтому я написал эту простую программу test.py, которая будет выполнять некоторые основные длинные операции:

from time import time
start = time()
q = 2 ** 1000000000
q += 3 << 1000000000
print(q.__sizeof__(), time() - start)

Я не получил то, что яожидается, так как после запуска команд time python2.6 test.py и time python3.1 test.py, соответственно, вывод был следующим:

(133333364, 0.37349200248718262)

real    0m35.586s
user    0m28.130s
sys 0m2.110s

и

133333360 0.312520027161

real    0m26.413s
user    0m17.330s
sys 0m2.190s

Я предположил, что результаты для обеих версийбудет близок при сравнении вывода команды time и действия внутри программы.Чем это объясняется?

Ответы [ 2 ]

3 голосов
/ 09 августа 2010

Может быть много объяснений, таких как другой набор каталогов (и zip-файлов) на sys.path, автоматически загружаемый / исполняемый код при инициализации, другие процессы, выполняющиеся на платформе - ваш код совсем не изолирован и не повторяется поэтому его результаты имеют очень мало значения. Используйте python -mtimeit, чтобы измерить многое, намного лучше.

Редактировать : некоторые цифры ...:

$ py26 -mtimeit 'q=2**1000000000; q+=3<<1000000000'
10 loops, best of 3: 466 msec per loop
$ py31 -mtimeit 'q=2**1000000000; q+=3<<1000000000'
10 loops, best of 3: 444 msec per loop

они точно измеряют время += (немного лучше / более оптимизировано в 3.1, повторяемо). Если вы хотите измерить увеличение смещения или до степени , то, конечно, вы не можете использовать литералы (поскольку выражения литералов вычисляются во время компиляции, а не во время выполнения: часть того, почему вы хотите, чтобы весь ваш значимый код был в функциях в модулях, , а не в коде верхнего уровня или в вашем основном скрипте ... так что компилятор может выполнять как можно большую часть работы, насколько это возможно несмотря на отсутствие каких-либо серьезных оптимизаций ;-). E.g.:

$ py31 -mtimeit -s't=2' 'q=t**1000000'
10 loops, best of 3: 19.4 msec per loop
$ py31 -mtimeit -s't=3' 'q=t<<1000000'
10000 loops, best of 3: 150 usec per loop

(просто требуется слишком много времени, чтобы сделать их с большим операндом RHS, который вы используете, и я теряю терпение ;-). Микширование операций, конечно, было бы печальной катастрофой с точки зрения измерения, поскольку относительно быстрые из них по существу исчезнут в миксе! -) К счастью, для такого микширования нет веской причины - в конце концов, timeit микро бенчмаркинг! -)

2 голосов
/ 09 августа 2010

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

from time import time
start = time()
q = 2 ** 1000000000 # number literal
q += 3 << 1000000000 # still a literal
print(q.__sizeof__(), time() - start)

Компилятор Python (!) Вычисляет q. Когда скрипт выполняется, интерпретатор берет время, загружает уже вычисленное значение и снова берет время. Теперь неудивительно, что два раза почти одинаковы.

time, с другой стороны, измеряет, сколько времени занимает полный цикл (компиляция + запуск).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...