Итак, я хотел сравнить производительность 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
banx 9 Авг 2010 в 02:14

2 ответа

Лучший ответ

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

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, с другой стороны, измеряет, сколько времени занимает полный запуск (компиляция + запуск).

2
Jochen Ritzel 8 Авг 2010 в 22:44

Может быть много объяснений, таких как другой набор каталогов (и 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, повторяемость). Если вы хотите измерить время сдвига или возведения в степень , то, конечно, вы не можете использовать литералы (поскольку литеральные выражения вычисляются во время компиляции, а не при запуске время: часть того, почему вы хотите, чтобы весь ваш важный код находился в функциях в модулях, не в коде верхнего уровня или в вашем основном скрипте ... чтобы компилятор мог выполнять столько же работы, сколько легко выполнимо, несмотря на отсутствие каких-либо серьезных оптимизаций ;-). Например.:

$ 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, в конце концов, предназначен для тестирования микро ! -)

3
Alex Martelli 8 Авг 2010 в 22:58