2014-10-10 45 views
1

我在Windows 8.1(x64)上使用sympy 0.7.5(通過pip安裝)和Python 3.4.2。請考慮這套短節目:sympy性能差

import sympy 
import time 

start = time.time() 
for i in range(100): 
    sympy.Point(12345.0, 54321.0) 
print('Elapsed (ms):', (time.time() - start) * 1000) 

它需要我的機器約22秒執行此。我在這裏錯過了什麼?

回答

2

當從浮點數生成sympy.Point時,它們會自動轉換爲有理數。這可能是一件好事(例如,如果你想避免浮點精度損失),但也可以很慢()。要禁用轉換爲Rational s pass evaluate=False,例如

%timeit sympy.Point(12345., 54321.) 
10 loops, best of 3: 31.8 ms per loop 

%timeit sympy.Point(12345., 54321., evaluate = False) 
10000 loops, best of 3: 22.3 us per loop 
+0

謝謝,它的工作原理!我想知道爲什麼這會產生這樣的性能影響 - 通過選擇一個合適的基數10分母來轉化爲理性的(在這種情況下)是平凡的。 事實上,我想避免精度損失。你可能會建議另一個庫支持基本的幾何計算,如計算多邊形質心,並沒有像這樣的性能問題? – 2014-10-10 19:01:29

+0

我無法評論爲什麼'Rational'比內置類型慢得多。請注意,精度損失通常並不如聽起來那麼糟糕,您可以看到的最明顯的問題是在計算之後等式只是近似值。 – 2014-10-10 20:01:03

0

而不是依賴於點經nsimplify您的積分轉換爲理性的形式,你可以通過在Rational包裹他們這樣做自己。然後你負起責任,確保你所代表正常的浮動:

>>> Rational(.3) 
5404319552844595/18014398509481984 
>>> Rational('.3') <--- smartest way to do so 
3/10 
>>> nsimplify(.3) <--- slowest way to do so 
3/10 

(但花車是整數或許應該被作爲特例處理)

0

就評論說,這個問題似乎少Sympy Version:1.0(使用Python 3.5.1運行)很重要。 以下程序僅給出「Evaluate = False」選項的第二個因子:

start = time.time() 
for i in range(100): 
    Point(12345.0, 54321.0) 
print('Elapsed (ms):', (time.time() - start) * 1000) 

Elapsed (ms): 14.796018600463867 

start = time.time() 
for i in range(100): 
    Point(12345.0, 54321.0, evaluate = False) 
print('Elapsed (ms):', (time.time() - start) * 1000) 

Elapsed (ms): 8.768081665039062