如果您的问题是关于一般地优化python代码(我认为应该是;),那么可以做各种各样的测试工作,但是首先:
您可能不应该过分地优化python代码! 如果您要使用最快的算法来解决问题,而python的处理速度不够快,则可能应该使用其他语言。
就是说,您可以采用几种方法(因为有时候,您确实确实想使python代码更快):
个人资料(先执行此 *** 作!)有很多分析python代码的方法,但是我将提到两种:(
cProfile或
profile)module和
PyCallGraph。个人资料
这是您实际上应该使用的方法,尽管解释结果可能会有些令人生畏。它通过记录何时进入或退出每个函数以及调用函数是什么(以及跟踪异常)来进行记录。
您可以像这样在cProfile中运行一个函数:
import cProfilecProfile.run('myFunction()', 'myFunction.profile')
然后查看结果:
import pstatsstats = pstats.Stats('myFunction.profile')stats.strip_dirs().sort_stats('time').print_stats()
这将向您显示大部分时间都花在哪些功能上。
PyCallGraphPyCallGraph提供了一种 最漂亮
,也可能是最简单的方法来分析python程序-这是了解程序时间的很好的入门指南,但是却增加了执行开销
运行pycallgraph:
pycallgraph graphviz ./myprogram.py
简单!您会得到一个png图形图像作为输出(也许过一会儿…)
使用图书馆如果您要尝试在python中执行某个已经存在的模块(甚至在标准库中),请改用该模块!
大多数标准库模块都是用C语言编写的,它们的执行速度比对等搜索(例如,bisection搜索)要快数百倍。
让翻译员尽您所能解释器将为您做一些事情,例如循环。真?是! 您可以使用
map,
reduce以及
filter关键字显著加快紧凑循环:
考虑:
for x in xrange(0, 100): doSomethingWithX(x)
vs:
map(doSomethingWithX, xrange(0,100))
显然,这 可能 会更快,因为解释器只需要处理一个语句即可,而不是两个,但这有点含糊……实际上,这样做有两个原因:
- 所有流控制(我们已经完成循环了……)都在解释器中完成
- doSomethingWithX函数名称仅解析一次
在for循环中,每次循环python都要检查
doSomethingWithX函数的确切位置!即使是缓存,这也有些开销。请记住,Python是一种解释性语言
(请注意,本节实际上是关于微小的优化,您不应该让它们影响您的常规可读编码风格!)如果您来自使用c或Fortran之类的编译语言进行编程的背景,那么关于不同的python语句的性能可能令人惊讶:
try:ing便宜,
ifing昂贵
如果您有这样的代码:
if somethingcrazy_happened: uhOhBetterDoSomething()else: doWhatWeNormallyDo()
而
doWhatWeNormallyDo()将抛出如果有什么疯狂的事例外,那么这将是更快的这样的安排你的代码:
try: doWhatWeNormallyDo()except SomethingCrazy: uhOhBetterDoSomething()
为什么?很好,口译员可以直接潜入并开始做您通常的工作;在第一种情况下, 每次 执行if语句 时
,解释器都必须查找一个符号,因为该名称可能引用自上次执行该语句以来的其他内容!(和名称查找,特别是如果
somethingcrazy_happened是
global可以的话)。你是说谁?
由于名称查找的开销,最好在函数中缓存全局值,然后将简单的布尔测试烘烤到这样的函数中:
未优化的功能:
def foo(): if condition_that_rarely_changes: doSomething() else: doSomethingElse()
优化的方法而不是使用变量,而是利用了解释器始终在函数上进行名称查找的事实!
条件成立时:
foo = doSomething # now foo() calls doSomething()
当条件变为假时:
yfoo = doSomethingElse # now foo() calls doSomethingElse()
PyPy是用python编写的python实现。当然,这意味着它将无限慢地运行代码吗?好吧,不。PyPy实际上使用即时编译器(JIT)运行python程序。
如果您不使用任何外部库(或者您使用的外部库与PyPy兼容),则这是一种(几乎可以肯定)加快程序中重复任务的极其简便的方法。
基本上,JIT可以生成代码,将做什么Python解释器会,但 多 快,因为它是一个单一的情况下产生的,而不是来处理每一个可能的法律Python表达式。
接下来看哪里当然,您应该首先考虑的是改进算法和数据结构,并考虑诸如缓存之类的事情,或者甚至是否首先需要做很多事情,但是无论如何:
python.org Wiki的此页面提供了许多有关如何加快python代码速度的信息,尽管其中有些过时了。
这是BDFL自己关于优化循环的主题。
即使我从有限的经验中也错过了很多东西,但是这个答案已经足够长了!
这一切都是基于我最近对某些python代码的经验,这些代码 还不够快
,我想再次强调一点,我真的不认为我建议的任何内容实际上是一个好主意,有时但是,您必须…
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)