加快python -c调用

时间:2019-05-15 18:29:36

标签: python sympy

我正在从PHP Web应用程序发出python命令行调用,以执行一些sympy分析(然后我解析回sympy输出)。

这些调用需要很长时间,但我认为更多的是python启动和代码解析/编译需要很多时间,而不是不等式系统本身的解决方案。

问题是我的程序随每次调用而改变:我总是解决不平等的另一个系统。没有静态结构,因此我只能导入例如LSE的系数。这是一个大小和结构各异的系统。所以(我认为),我不能使用pyc文件。

以下是两个示例呼叫:

/usr/bin/python -c "from sympy import Intersection; from sympy import solveset; from sympy import S; from sympy.abc import x; from sympy.functions.elementary.miscellaneous import Min, Max; print Intersection(*[solveset(p, x, S.Reals) for p in [(x > 4.0000), (x < 6.0000)]])" 2>&1


/usr/bin/python -c "from sympy import Intersection; from sympy import solveset; from sympy import S; from sympy.abc import x; from sympy.functions.elementary.miscellaneous import Min, Max; print Intersection(*[solveset(p, x, S.Reals) for p in [(x > 4.0000), (x < 6.0000), (((x) * 4.0000 + 5.0000) > 5.0000)]])" 2>&1

不等式的系统可能会变得很大,并且一直在变化。这是带有非线性表达式的一个:

/usr/bin/python -c "from sympy import Intersection; from sympy import solveset; from sympy import S; from sympy.abc import x; from sympy.functions.elementary.miscellaneous import Min, Max; print Intersection(*[solveset(p, x, S.Reals) for p in [(x > 4.0000), (x < 6.0000), ((x * (Min(Max(x, 4.0000), 5.0000))) > 7.0000), ((Min(Max(x, 4.0000), 5.0000)) > 5.0000)]])" 2>&1

是否有任何命令行选项或配置设置可以加快这些程序的速度?

也许我可以预编译sympy导入?

编辑:也许有一种python模式可以守护python,它使用导入的sympy库来等待我的请求?然后我只将print Intersection(...)命令发送给它吗?

编辑2

由于有一个答案,我尝试了pypy软件包。但不幸的是,我无法报告运行时间有所改善。使用标准的python 2.7,我得到:

# time /usr/bin/python -c "from sympy import Intersection; from sympy import solveset; from sympy import S; from sympy.abc import x; from sympy.functions.elementary.miscellaneous import Min, Max; print Intersection(*[solveset(p, x, S.Reals) for p in [(x > 4.0000), (x < 6.0000), ((x * (Min(Max(x, 4.0000), 5.0000))) > 7.0000), ((Min(Max(x, 4.0000), 5.0000)) > 5.0000)]])"
EmptySet()

real    0m3.080s
user    0m2.920s
sys 0m0.050s

我有pypy:

# time pypy -c "from sympy import Intersection; from sympy import solveset; from sympy import S; from sympy.abc import x; from sympy.functions.elementary.miscellaneous import Min, Max; print Intersection(*[solveset(p, x, S.Reals) for p in [(x > 4.0000), (x < 6.0000), ((x * (Min(Max(x, 4.0000), 5.0000))) > 7.0000), ((Min(Max(x, 4.0000), 5.0000)) > 5.0000)]])"
EmptySet()

real    0m6.816s
user    0m6.660s
sys 0m0.080s

2 个答案:

答案 0 :(得分:2)

SymPy的启动速度很慢,但并不慢。您看到的缓慢只是在SymPy下您的特定方法缓慢。通过使用int而不是float,可以使示例速度更快。

大部分时间都用在求解集上,这对于您的许多简单关系似乎都是不必要的。例如,仅使用as_set

就没必要用x<4调用Solveset了。
In [7]: (x<4).as_set()                                                                                                            
Out[7]: (-∞, 4)

您还可以将其他条件重写为更直接的形式,例如

In [11]: piecewise_fold(Min(Max(x, 4.0000), 5.0000).rewrite(Piecewise))                                                           
Out[11]: 
⎧5.0  for x ≥ 5.0
⎪                
⎨4.0  for x ≤ 4.0
⎪                
⎩ x    otherwise 

我认为您可以将一种比setset更有效的解决方案组合在一起。我建议创建一个比可以高效地调度简单案例(例如x<4并仅在更复杂的案例中调用solveset)更有效的函数。

答案 1 :(得分:1)

有很多方法可以加快Python程序的速度。推荐的方法是优化算法和code(尝试python -m cProfile yourfile.py),最简单的方法是使用PyPy(用于长时间运行代码的JIT编译器)。其他选项包括Shed Skin(使用C ++的静态编译器),Numba(使用装饰器和LLVM的静态编译器),Cython(使用类型和C的静态编译器)和Nuitka

在您的情况下,至少将命令行代码放入.py文件中,并运行python -m compileall .compile that to .pyc bytecode可以使解析步骤更快,但是使用静态编译器跳过可以忽略不计完全是翻译。

如果您要制作REST API,根据the Falcon frameworkthis benchmark是最快的Python FastCGI服务器之一;这是a little SymPy REST API server demo project