我已经看到了球碰撞检测问题的各种答案,解释了为什么 sqrt 操作很慢,为什么绝对值操作在浮点数上很快等等。我如何找出哪些操作昂贵而哪些操作不昂贵?
基本上,我正在寻找一个可以了解所有Python库函数的实现的资源。当人们说这些事情时,他们实际上并没有考虑这些东西是如何在 C 中实现的,是吗?
谢谢,希望了解有关这种灵活语言的实现细节的更多信息。
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 '导入数学; x = 42.5; y = 17.2; r = 50.0' 'math.sqrt(x**2 + y**2) <= r' 1000000 loops, best of 3: 0.744 usec per loop $ python -m timeit -s 'import math; x = 42.5; y = 17.2; r = 50.0' 'math.hypot(x, y) <= r' 1000000 loops, best of 3: 0.374 usec per loop $ python -m timeit -s 'import math; x = 42.5; y = 17.2; r = 50.0' 'x**2 + y**2 <= r**2' 1000000 loops, best of 3: 0.724 usec per loop
所以
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