Python性能 – 你有没有必要重写别的东西?

有没有人有过Python的代码,结果不够快?

我的意思是,你被迫select另一种语言,因为它?

我们正在研究使用Python来处理几个较大的项目,我的感觉是,在大多数情况下,Python对于大多数场景来说足够快(相对于Java而言),因为它依赖于优化的C例程。

我想看看是否有人从Python开始, 但是由于性能的原因,最终还是要去别的地方。

谢谢。

是的,我有。 我为bcp输出文件编写了一个二进制(长度前缀而不是分隔)的行计数程序,最后不得不在C中重做它,因为python的速度太慢了。 这个程序非常小(用C重写它只花了几天的时间),所以我没有打算尝试构build一个混合应用程序(用C编写的中央例程的python粘贴),但是这也会有是一条可行的路线。

具有性能关键位的更大的应用程序可以用C和更高级语言的组合来编写。 您可以使用Python的接口在C中编写性能至关重要的部分,以用于系统的其余部分。 SWIG , Pyrex或Boost.Python (如果你使用的是C ++)都提供了很好的机制来为你的Python接口做pipe道工作。 python的C API比Tcl或Lua的C API更复杂,但手动构build并不可行。 有关手动构build的Python / C API的示例,请查看cx_Oracle 。

这种方法已被用于相当多的成功的应用程序,可以追溯到20世纪70年代(我知道)。 Mozilla基本上是用Javascript编写的,以C语言编写的核心引擎。 几个 CAD软件包 , Interleaf (一个技术文档发布系统),当然EMACS基本上都是用LISP编写的,具有中央C语言,汇编语言或其他核心。 不less商业和开源应用程序(例如Chandler或Sungard Front Arena )使用embedded式Python解释器,并在Python中实现应用程序的大部分。

编辑:在回答荷兰语大师的评论中,让一个具有C或C ++编程技巧的人在Python项目团队中给你select编写一些速度的应用程序。 您期望获得显着性能增益的领域是应用程序在大数据结构或大量数据上进行高度迭代的地方。 在上面的行计数器的情况下,它必须吸入总计几千兆字节的一系列文件,并且经历读取可变长度前缀的过程,并使用该过程来确定数据字段的长度。 大部分字段都很短(只有几个字节)。 这是有点琐碎和非常低的水平和迭代,这使得它自然适合C.

许多python库(如numpy , cElementTree或cStringIO)都使用了一个优化的C核和一个python API,可以方便地处理数据。 例如,numpy具有用C语言编写的matrix数据结构和操作,它们完成所有的工作,还有一个Python API,用于在总体级别上提供服务。

这比人们愿意承认的要难得多。

例如,我可以编写一个在Python中比在C中执行得更好的程序。该语句的错误结论是“Python比C快”。 实际上,这可能是因为我有更多的Python经验,最佳实践和标准库。

事实上,没有人能真正回答你的问题,除非他们确定他们可以用这两种语言创build一个最佳解决scheme,这是不太可能的。 换句话说,“我的C解决scheme比我的Python解决scheme更快”与“C比Python更快”不一样,

我敢打赌,Guido Van Rossum可以为亚当和达斯汀的问题编写Python解决scheme,performance相当好。

我的经验法则是,除非你正在编写需要计算时钟周期的应用程序,否则你可能在Python中达到可接受的性能。

添加我的$ 0.02的logging。

我的工作涉及到开发数百亿字节数据的数字模型。 困难的问题是快速提出创收解决scheme(即上市时间)。 要在商业上取得成功,解决scheme也必须快速执行 (在最短的时间内计算解决scheme)。

对于我们来说,Python已经被certificate是开发解决scheme的一个很好的select,其原因是:开发时间快,语言expression丰富,库丰富等。但是为了满足执行速度的需求,我们采用了“混合”方法,已经提到过了。

  1. 使用numpy计算密集的部分。 我们以1.1倍到2.5倍于原生C ++解决scheme的速度,使用numpy代码less,缺陷less,开发时间短。
  2. 酸洗(Python的对象序列化)中间结果,以尽量减less重新计算。 我们的系统的性质需要对相同的数据进行多个步骤,所以我们“记住”结果并在可能的情况下重新使用它们。
  3. 分析和select更好的algorithm。 在其他回复中已经说过了,但是我会重复一遍:我们剔除cProfile并尝试用更好的algorithm来replace热点。 不适用于所有情况。
  4. 去C ++。 如果以上失败,我们称之为C ++库。 我们使用PyBindGen编写我们的Python / C ++包装器。 我们发现它远远优于SWIG,SIP和Boost.Python,因为它可以生成直接的Python C API代码,而不需要中间层。

阅读这份清单,你可能会想:“这是多么重要的工作!我会在第一时间在[C / C ++ / Java /汇编程序]中完成并完成它。

让我来看看。 使用Python,我们能够在5周内生成一个有效的创收应用程序,而在其他语言中,以前需要3个月来处理类似范围的项目。 这包括优化我们发现速度较慢的Python部分所需的时间。

在uni的时候,我们正在编写一个计算机视觉系统来分析基于video剪辑的人类行为。 我们使用了python,因为PIL非常出色,加快了开发速度,让我们可以轻松访问从video中提取的图像帧,以便转换为数组等。

对于我们所需要的90%是好的,因为图像分辨率相当低,速度并不差。 然而,一些过程需要一些复杂的逐像素计算和卷积,这是非常缓慢的。 对于这些特定的区域,我们用C重写了循环的最里面的部分,只是更新了旧的Python函数来调用C函数。

这给了我们两全其美的好处。 python提供的数据访问非常方便,能够快速开发,然后是C的直线运算速度,用于最密集的计算。

不太远。 我工作的公司有一个分子模拟引擎和一堆用python编写的程序,用于处理大型的千兆字节数据集。 我们所有的分析软件现在都是用Python编写的,因为它具有开发灵活性和时间上的巨大优势。

如果有些东西不够快,我们用cProfile分析它,找出瓶颈。 通常有一个或两个函数占用运行时间的80%或90%。 然后,我们将这些函数重写为C,这使得Python使用C API变得简单。 在许多情况下,这会导致一个数量级或更多的加速。 问题没有了。 然后我们继续用Python来继续写所有的东西。 冲洗并重复…

对于整个模块或类,我们倾向于使用Boost.python,它可能有点熊,但最终效果不错。 如果它只是一个或两个函数,如果项目已经在使用scipy,我们有时会将它与scipy.weave联系起来。

每当我发现一个Python的瓶颈,我把C中的代码改写为一个Python模块。

例如,我有一些硬件发送图像像素为4字节0RGB。 在Python中将8M从0RGB转换为RGB需要很长时间,所以我将它重写为Python模块。

编写Python(或其他更高级别的语言)比用C编写要快得多,所以我使用Python直到不能。

这种问题很可能会在语言人士之间开始一场宗教战争,所以让我回答一下。

对于大多数情况下,在当今的计算环境中,编程语言的select应该基于你可以高效地编程,编程良好,什么让你快乐,而不是语言的性能特征。 而且,编程任何系统时,优化通常应该是最后的关注点。

典型的python方法是开始用python编写你的程序,然后如果你注意到了应用程序的性能,并试图优化python中的热点。 如果优化python代码仍然不够好,那么缩小你的代码的区域应该被重写为C中的python模块。如果即使所有的程序不够快,你也可以改变语言,或者考虑扩展硬件或并发性。

这是很长的答案,直接回答你的问题; 不,python(有时用C扩展)已经足够快了,我需要它做的一切。 我唯一一次深入C就是获得那些没有python绑定的东西。

编辑:我的背景是一个大型.com的python程序员,我们使用python从我们网站的前端一直到所有的后台系统。 Python是一种企业级语言。

在为特定数据types实现特定的memcache服务器时,存储后端的内存效率会更高,查找时间会因位查找操作( 即:O(1)查找 )而降低。

我在2天内用Python编写了所有的协议实现和事件驱动的守护进程部分,给我们足够的时间来testingfunction,并关注性能,而团队正在validation协议一致性和其他位。

考虑到像Pyrex这样的工具,为C语言实现C扩展对于任何在C语言中有经验的开发人员来说都是微不足道的。我在C中重写了基于基于Radix Tree的存储后端,并在一天内将它变成了Pyrex的Python模块。 475K前缀的内存使用量从90MB降至8MB。 查询性能提高了1200%。

今天,这个应用程序使用pyevent (libevent的Python接口)运行,新的存储后端在一个适度的单核服务器上每秒处理8000个查询,作为一个进程守护进程运行(感谢libevent),消耗less于40MB的内存Python解释器),同时处理300多个同时连接。

这是一个在不到5天的时间内为生产质量而devise和实施的项目。 如果没有Python和Pyrex,将需要更长的时间。

我们可以通过使用function更强大的服务器来解决性能问题,并切换到多进程/多实例模型,同时使代码和pipe理任务复杂化,同时还需要更大的内存空间。

我想你正走在Python的正确轨道上。

我曾经在python中做过很多事情来处理日志处理。 当他们跑得不够快时,我会用ocaml重写它们。

在很多情况下,python很好,我很高兴。 在某些情况下,当它开始接近23个小时做一天的日志,我会重写。 🙂

我想指出的是,即使在这种情况下,我也许只是简单地分析一下python代码,find更快乐的python实现。

你总是可以用Python编写你的应用程序的一部分。 不是每个组件对于性能同样重要。 Python本身可以很容易地与C ++集成,也可以通过Jython与Java集成,或者通过IronPython与.NET集成。

顺便说一下,在某些基准testing中,IronPython比Python的C实现更有效率。

我已经工作了一段时间,开发一个应用程序,可以处理大型的结构化数据,存储在几千兆字节厚的数据库中,而且Python已经足够了。 该应用程序具有GUI客户端和多个控件(列表,树,笔记本,虚拟列表等)以及控制台服务器。

我们遇到了一些性能方面的问题,但是这些问题主要与糟糕的algorithmdevise或者数据库引擎的局限性(我们使用Oracle,MS-SQL,MySQL和BerkeleyDB用于速度优化)有关。 一旦你知道如何正确地使用标准库(用C语言编写),你可以使你的代码真的很快。

正如其他人所说 – 任何计算密集型algorithm,依赖于位填充的代码,一些内存受限的计算 – 都可以在原始C / C ++中完成,以节省CPU /内存(或任何其他技巧),但是整个用户交互,数据库处理,error handling – 所有使应用程序真正运行的东西都可以用Python编写,并且可以保持响应能力和体面的整体性能。

我现在正在python开发好几年了。 最近我不得不列出目录中的所有文件,并build立一个文件名,大小,属性和修改date的结构。 我用os.listdiros.stat做了这个。 代码非常快,但是目录中的条目越多,我的代码就越慢地被共同映射到列出相同目录的其他文件pipe理器,所以我使用SWIG / C ++重写了代码,并且真的让代码惊讶得多了。

是的,两次:

  • 一个audioDSP应用程序使用C ++完全重写,因为我无法在Python中获得适当的性能。 我不认为Python的实现浪费了,因为它让我可以很容易地将概念原型化,而且C ++端口也很stream畅,因为我有一个工作参考实现。

  • 一个程序化的graphics渲染项目,在Python中生成大的2D纹理贴图需要很长时间; 我写了一个C ++ DLL,并使用ctypes / windll从Python中使用它。

不,我从来不需要重写。 实际上,我在Maya 8.5中开始使用Python。 Maya 8之前,唯一可用的脚本语言是MEL(Maya Expression Language)。 Python实际上比它所包含的内置语言更快。

Python处理复杂数据types的能力也使得它更快,因为MEL只能存储单维数组(并且没有指针)。 这需要通过使用多个并行数组或通过使用慢串连接来伪造multidimensional array。

一个月前,我有这个用Python编写的小程序(用于工作)分析日志。 当日志文件的数量增长,程序开始非常缓慢,我想我可以重写它在Java中。

我非常有趣 将相同的algorithm从Python迁移到Java需要一整天的时间。 在一天结束的时候,一些基准testing显示,我的Java程序比Python的程序慢了20%/ 25%。 这对我来说是一个惊喜。

该algorithm第二次写作也显示了一些优化是可能的。 所以在两个小时之内,我完全重写了Python中的所有内容,比原来的Python实现快了40%(因此比我的Java版本快得多)。

所以:

  1. Python是一种缓慢的语言,但对于某些任务来说,它可能会更快,而其他所谓的更快的语言

  2. 如果您不得不花费时间用执行速度更快但开发时间较慢的语言(大多数语言)编写某些语言,请考虑使用相同的时间来分析问题,search库,configuration文件,然后编写更好的Python代码。

我曾经为模拟器写过一个伪随机数发生器。 我首先用Python写的,但是Python被certificate太慢了, 我最终用C语言重写了它,即使这样很慢,但并不像Python那么慢。

幸运的是,连接Python和C是相当容易的,所以我能够将PRNG编写为C模块,并且仍然使用Python编写模拟器的其余部分。

以下链接提供了多种计算机语言之间的比较。 它应该让你了解一些Python在不同问题领域的长处和短处。

计算机语言基准游戏

我正在用Erok的名字(原来的Kore的反向)在Python中重写Perl程序OpenKore 。 到目前为止,Python被certificate是一个总体上更好的语言,尤其是因为其强大的stringparsingfunction,不需要使用正则expression式,这实际上加快了其文件parsing。

我之前一般不会重写C:

  • 轮廓
  • 用bettealgorithm重写(通常这已经足够了)
  • 重新编写具有低级性能的Python代码(但从来没有达到非pythonic /不可读代码)
  • 花一些时间重新检查库不能做到这一点(首先在stdlib,或外部库)
  • 尝试psyco /其他实现(很less达到真正的速度提升在我的情况)

然后,有时候我创build了一个共享库来执行繁重的matrix计算代码(numarray无法完成),并用ctypes调用它:

  • 简单的编写/build立/testing一个纯C的.so / dll,
  • 简单地把C封装到python函数中(也就是说,如果你使用基本的数据types,那么ctypes会为你调用正确的参数做所有的工作),并且肯定足够快。