PEP 484では、「パフォーマンスの最適化にタイプヒントを使用することは、読者の練習として残されています。これはCommon Lispのように、型宣言を使って、私が何をやっているかを誓ったときに、パフォーマンス集約型の関数の中で型のディスパッチを脇に置くことができることを示唆しています。これを自分自身で試してみるために、私はpシリーズを使ってpiを計算するための少しのベンチマークを書きました。パフォーマンスの最適化のためのPython 3タイプのヒント
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)
私がエミュレートしようとしている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)
私マシンでは、sbclで実行されるLispバージョンは、低速バージョンでは22秒、タイプヒントバージョンでは4秒、Cと同じです。CPythonは、ナイーブバージョンで162秒、タイプヒントバージョンで141秒です。 Pypyはタイプヒントのないバージョンをわずか5秒で実行しますが、ライブラリのサポートは私のプロジェクトには十分ではありません。
lispやPypyに近いパフォーマンスを得るためにヒント付きのバージョンを改善する方法はありますか?
あなたは一般的なパフォーマンスを助けるためにタイプヒントを期待してはいけないと言っていますか? PEPの "エクササイズ"は、それがすべきことを示唆している。 – Juanote
@Juanoteいいえ、一般的ではありません。あなたはそれを行う方法を理解している限り、自分のコードでそれらを利用することができます、それはエクササイズです。しかし、他の人のコード(CPythonを読んでください)が、文書化されていない限り、タイプヒントを使って何かをすることは期待できません。 – Goyo
私は参照してください。 Common Lispで示したことを私にさせてくれる別の言語機能がありますか、または速い演算のためにCに落とす必要がありますか?私はむしろPythonの新機能であり、セマンティクスの点ではCommon Lispに非常に近いと思われますが、私が知る限りでは、高速な宣言は利用できません。 – Juanote