我需要加快一个函数的速度。应该使用cython、ctypes还是其他方法?

8 投票
4 回答
3192 浏览
提问于 2025-04-15 21:39

我正在通过编写一种遗传编程类型的应用程序来学习Python,感觉非常有趣。

在这个网站上,我得到了Torsten Marek、Paul Hankin和Alex Martelli的很多好建议。

这个程序有四个主要功能:

  • 随机生成一个表达式树。
  • 评估这个树的适应度。
  • 进行交叉繁殖。
  • 进行变异。

因为生成、交叉繁殖和变异这三个功能都会调用“评估适应度”,所以评估适应度的功能是最繁忙的,也是速度上的主要瓶颈。

遗传算法的特点就是需要在一个巨大的解决方案空间中进行搜索,所以速度越快越好。我想加快这几个功能的速度。首先我会从适应度评估器开始。我的问题是,怎样做才能达到最佳效果。我正在研究cython、ctypes和“链接与嵌入”。这些对我来说都是新东西,目前还不太懂,但我期待着学习其中一个,最终掌握所有这些。

适应度函数需要将表达式树的值与目标表达式的值进行比较。因此,它将包含一个后缀评估器,用于按后缀顺序读取树。我所有的代码都是用Python写的。

我需要建议,现在应该学习和使用cython、ctypes还是链接与嵌入。

谢谢。

4 个回答

0

试着让你的适应度函数支持记忆化。这样的话,之前重复的调用就可以用快速的字典查找来替代,省去重复计算的时间。

3

Cython 是一种快速完成工作的工具,你可以直接用 Cython 写你的算法,或者先用 C 语言写好算法,再通过 Cython 把它和 Python 连接起来。

我的建议是:学习 Cython。

14

先不管其他人的回答。你首先要学会使用性能分析工具。Python自带一个叫做profile或cProfile的工具;你应该学会如何查看结果,并分析出真正的瓶颈在哪里。优化的目标有三个:减少每次调用所花的时间,减少调用的次数,以及减少内存使用,从而减少磁盘的频繁读写。

第一个目标相对简单。性能分析工具会告诉你哪些函数最耗时,你可以直接去优化这些函数。

第二个和第三个目标就难一些,因为这意味着你需要改变算法,以减少调用次数。找出那些调用次数很多的函数,想办法减少对它们的调用。利用内置的集合,它们的优化做得很好。

如果你在处理大量数字和数组,建议你看看pandas、Numpy/Scipy这些第三方模块;它们是处理数组和表格数据的高效C库。

你还可以尝试使用PyPy。PyPy可以进行即时编译,并且能做比CPython更高级的优化,而且不需要你修改Python代码。不过,针对CPython优化的代码和针对PyPy优化的代码可能会有很大不同。

接下来可以试试Cython。Cython是一种与Python略有不同的语言,实际上可以把Cython看作是带有类型的Python风格语法的C语言。

对于那些在非常紧凑的循环中,无法通过其他方式再优化的代码部分,你可能需要将其重写为C扩展。Python对用C扩展的支持非常好。在PyPy中,扩展PyPy的最佳方式是使用cffi。

撰写回答