Is math.sqrt or **.5 more Pythonic?



使用 math.sqrt(( 还是 **.5 更 pythonic?例如,编写 math.sqrt(2( 或 2**.5 是否更 python?

pythonic的影响包括(1(更具可读性,(2(更常见,(3(更快或更高效。

没关系。math.sqrt,被命名,本身的可读性略微高,但在更大的方程的背景下,可能会分解更具可读性的数学** 0.5由于缺乏直接解释器支持(函数调用调度是通用的,幂具有专用字节码(,math.sqrt的速度会稍微慢一些(如果from math import sqrt是为了保存属性查找而变慢(,但在 99.999% 的情况下,速度差异无关紧要。更新:实际上,在检查时,math.sqrt的速度要快得多(在我的CPython 3.7.2 x64 Linux构建中,在小int输入上花费的时间减少了~18%,在float输入上花费的时间减少了~6%(;显然,对幂的直接字节码支持并没有超过通用幂的成本,因为它需要做一个平方根。

基本上,做使你的代码在上下文中看起来漂亮/可读的事情。


对于那些关心的人,我的ipython3基准基本上只是:

>>> import math
>>> %%timeit r = tuple(range(100))  # To get baseline for overhead not associated with square root
... for i in r:
...     i
...
1.6 μs ± 2.04 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
>>> %%timeit r = tuple(range(100))
... for i in r:
...     i ** 0.5
...
14.4 μs ± 23 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
>>> %%timeit r = tuple(range(100))
... for i in r:
...     math.sqrt(i)
...
12.1 μs ± 43.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
>>> %%timeit r = tuple(map(float, range(100)))
... for i in r:
...     i ** 0.5
...
11.1 μs ± 31 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
>>> %%timeit r = tuple(map(float, range(100)))
... for i in r:
...     math.sqrt(i)
...
10.5 μs ± 5.61 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

从每个开销中减去基线开销以获得仅平方根运算的成本,最终的性能差异对于小ints快~18%,对于等效的floats快~6%(避免进行类型转换,对于** 0.5,不要花任何时间查看int的幂是否有效(。

相关内容

最新更新