Почему Python работает быстрее при объявлении целочисленной переменной с помощью int()?
При программировании алгоритма, который использует только целочисленную арифметику, я замечаю, что Python этим не воспользовался.
Поэтому я попробовал следующий код, чтобы увидеть эффект "явного" объявления
import time
repeat = 1000000
start = time.time()
x = 0
for i in range(repeat):
x += 1
no_type_time = time.time() - start
start = time.time()
y = int(0)
for i in range(repeat):
y += 1
int_time = time.time() - start
print('{} - No type'.format(no_type_time))
print('{} - Int'.format(int_time))
Вывод кода был следующим:
0.0692429542542 - No type
0.0545210838318 - Int
Я предполагаю, что это как-то связано с тем, что Python является динамически типизированным языком. Но когда я пытаюсь выяснить тип переменных, используя type(x) и type(y), выводим int. Что любопытно, потому что я также выполнил некоторые тесты, используя x = float(0), и результат очень близок к результату без "объявления" типа.
Я хотел бы знать, почему это происходит, и, если возможно, получить некоторую ссылку из документации Python, объясняющей это.
3 ответа
От точности на поплавках в вашем str.format
вывод (12 значащих цифр), мы можем видеть, что вы, вероятно, на Python 2.
Python 2 создает явный список миллионов целых при запуске range(repeat)
, что медленно. Он также сохраняет память для всех этих целых, поэтому range(repeat)
медленнее во второй раз. Скорее всего, это источник разницы во времени, а не какое-либо отношение к int
,
На Python 2 почти всегда лучше использовать xrange
вместо range
, xrange
генерирует целые по требованию, избегая затрат в памяти и времени на выделение целого списка:
for i in xrange(repeat):
do_stuff()
Я не могу воспроизвести на Linux. Отметьте это:
• реальное: фактическое время, потраченное на запуск процесса от начала до конца, как если бы оно измерялось человеком с секундомером
• пользователь: совокупное время, затраченное всеми процессорами во время вычислений.
• sys: совокупное время, потраченное всеми процессорами на системные задачи, такие как выделение памяти.
→ time python type.py
real 0m0.219s
user 0m0.000s
sys 0m0.000s
→ time python without_type.py
real 0m0.133s
user 0m0.000s
sys 0m0.000s
Это происходит потому, что Python кэширует и повторно использует некоторые неизменяемые встроенные объекты, даже если они "хранятся" как разные переменные
>>> a = 1
>>> id(a)
56188528L
>>> b = int(1)
>>> id(b)
56188528L
Python не должен был выделять какую-либо память или создавать новый объект для второй переменной. Это просто повторное использование неизменяемого целочисленного объекта, который уже был создан.
Если вы поместили свои временные тесты в разные файлы и запускали их отдельно, или если вы запускали int(1)
Сначала протестируйте, вы бы увидели разные результаты.