Реализация функций Python
Я видел различные ответы на вопрос об обнаружении столкновения шаров, объясняющие, почему операции sqrt выполняются медленно, почему операции с абсолютными значениями выполняются быстро на плавающих элементах и т. Д. Как узнать, какие операции являются дорогостоящими, а какие нет?
По сути, я ищу ресурс, где я могу узнать о реализации всех функций библиотеки Python. Когда люди говорят такие вещи, они на самом деле не думают о том, как эти вещи реализованы в C, не так ли?
Спасибо, желая узнать больше о деталях реализации на этом изящном языке.
4 ответа
Python, как и любой другой язык, переводится в машинный код и затем запускается. Так что да, они могли бы говорить о деталях реализации низкого уровня.
В любом случае, лучший способ узнать о быстродействии различных функций Python - взглянуть на исходный код.
Повеселись!
РЕДАКТИРОВАТЬ: Этот совет на самом деле относится к любому проекту с открытым исходным кодом, с которым я работал: Есть проблемы? Посмотрите на исходный код, и все будет в порядке.
Вы узнаете, какие операции медленные, а какие быстрые, используя модуль timeit.
Например, давайте сравним различные методы проверки, попадает ли точка в круг, из командной строки:
python -m timeit -s 'import math; x = 42.5; y = 17.2; r = 50.0' 'math.sqrt(x**2 + y**2) <= r'
python -m timeit -s 'import math; x = 42.5; y = 17.2; r = 50.0' 'math.hypot(x, y) <= r'
python -m timeit -s 'import math; x = 42.5; y = 17.2; r = 50.0' 'x**2 + y**2 <= r**2'
На моей машине результаты таковы:
$ python -m timeit -s 'import math; х = 42,5; у = 17,2; r = 50,0' 'math.sqrt(x**2 + y**2) <= r' 1000000 петель, лучшее из 3: 0,744 мксек на петлю $ python -m timeit -s 'import math; х = 42,5; у = 17,2; r = 50,0' 'math.hypot(x, y) <= r' 1000000 петель, лучшее из 3: 0,374 мксек на петлю $ python -m timeit -s 'import math; х = 42,5; у = 17,2; r = 50,0' 'x**2 + y**2 <= r**2' 1000000 циклов, лучшее из 3: 0,724 пользователя на цикл
так math.hypot
выигрывает! Кстати, если вы удалите поиск точечных имен из внутреннего цикла, вы получите несколько лучшие результаты:
$ python -m timeit -s 'from math import hypot; x = 42.5; y = 17.2; r = 50.0' 'hypot(x, y) <= r'
1000000 loops, best of 3: 0.334 usec per loop
Если вы ищете советы по скорости Python в целом, эти советы по производительности являются хорошим источником.
Стандартная библиотека Python включает дизассемблер:
>>> def foo(): print
...
>>> import dis
>>> dis.dis(foo)
1 0 PRINT_NEWLINE
1 LOAD_CONST 0 (None)
4 RETURN_VALUE
Это не работает на все, хотя:
>>> from math import sqrt
>>> import dis
>>> dis.dis(sqrt)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/dis.py", line 48, in dis
type(x).__name__
TypeError: don't know how to disassemble builtin_function_or_method objects