Каково обоснование рекомендуемого использования циклических конструкций в стиле for i in xrange(...)
в Python? Для простого целочисленного цикла разница в накладных расходах существенна. Я провел простой тест с использованием двух частей кода:
Файл idiomatic.py
:
#!/usr/bin/env python
M = 10000
N = 10000
if __name__ == "__main__":
x, y = 0, 0
for x in xrange(N):
for y in xrange(M):
pass
Файл cstyle.py
:
#!/usr/bin/env python
M = 10000
N = 10000
if __name__ == "__main__":
x, y = 0, 0
while x < N:
while y < M:
y += 1
x += 1
Результаты профилирования были следующими:
bash-3.1$ time python cstyle.py
real 0m0.109s
user 0m0.015s
sys 0m0.000s
bash-3.1$ time python idiomatic.py
real 0m4.492s
user 0m0.000s
sys 0m0.031s
Я могу понять, почему версия Pythonic медленнее - я полагаю, что это во многом связано с вызовом xrange N раз, возможно, это можно было бы устранить, если бы был способ перемотки генератора. Однако, с такой разницей во времени исполнения, почему бы предпочесть использовать версию Pythonic?
Редактировать: Я снова провел тесты, используя код, предоставленный г-ном Мартелли, и теперь результаты были действительно лучше:
Я думал, что перечислю выводы из этой ветки здесь:
1) Множество кода в области видимости модуля - плохая идея, , даже если код заключен в блок if __name__ == "__main__":
.
2) * Как ни странно, изменение кода, принадлежащего thebadone
к моей неверной версии (позволяя y расти без сброса), дало небольшую разницу в производительности, даже для больших значений M и N.