2014-10-10 130 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