Jua*_*ote 8 python type-hinting python-3.x
PEP 484说"使用类型提示进行性能优化是留给读者的练习." 这告诉我,就像Common Lisp一样,当我发誓我知道自己在做什么时,类型声明可用于在性能密集型函数中预留类型调度.为了自己尝试这个,我用一个p系列计算了一个基准来计算pi.首先,我以天真的方式做,然后我尝试聪明并利用类型提示的性能:
import math
import time
def baselpi0(n):
baselsum = 0;
for i in range(1,n):
baselsum += 1.0 / (i * i)
return math.sqrt(6.0 * baselsum)
def baselpi1(n : int) -> float:
n = float(n)
baselsum = 0.0
i = 1.0
while i < n:
baselsum += 1.0 / (i * i)
i += 1.0
return math.sqrt(6.0 * baselsum)
start = time.time()
print(baselpi0(1000000000))
end = time.time()
print(end - start)
start = time.time()
print(baselpi1(1000000000))
end = time.time()
print(end - start)
Run Code Online (Sandbox Code Playgroud)
我试图模仿的Common Lisp类比是:
(defun baselpi0 (n)
(let ((baselsum 0.0d0))
(loop for i from 1 to n do
(setf baselsum (+ baselsum (/ 1.0 (* i i)))))
(sqrt (* 6 baselsum))))
(defun baselpi1 (n)
(let ((baselsum 0.0d0)
(n (coerce n 'double-float)))
(declare (type double-float baselsum n)
(optimize (speed 3) (safety 0) (debug 0)))
(loop for i from 1.0d0 to n do
(setf baselsum (+ baselsum (/ 1.0d0 (* i i)))))
(sqrt (* 6.0d0 baselsum))))
(time (princ (baselpi0 1000000000)))
(time (princ (baselpi1 1000000000)))
(exit)
Run Code Online (Sandbox Code Playgroud)
在我的机器上,使用sbcl运行的lisp版本对于慢版本需要22秒,对于类型提示版本需要4秒,与C相同.对于朴素版本,CPython需要162秒,对于类型提示版本需要141秒.Pypy在不到5秒的时间内运行非类型提示版本,但是库支持对我的项目来说还不够好.
有没有办法可以改进我的类型暗示版本,以获得更接近lisp或Pypy的性能?
速度差异不是由于类型提示.Python 目前,在可预见的未来,只会丢弃您提供的任何提示,并继续像往常一样动态执行.
这是因为在一种情况下,您在整个代码中使用浮动算法(这会导致更快的执行),而在另一种情况下则不会.
例证:baselpi1
改为:
def baselpi1(n : int) -> float:
n = float(n)
baselsum = 0
i = 1
while i < n:
baselsum += 1.0 / (i * i)
i += 1
return math.sqrt(6.0 * baselsum)
Run Code Online (Sandbox Code Playgroud)
现在来看看执行时间:
3.141591698659554
0.2511475086212158
3.141591698659554
0.4525010585784912
Run Code Online (Sandbox Code Playgroud)
是的,它慢了.
归档时间: |
|
查看次数: |
1420 次 |
最近记录: |