优化Python代码

优化Python代码,第1张

优化Python代码

如果您的问题是关于一般地优化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()

这将向您显示大部分时间都花在哪些功能上。

PyCallGraph

PyCallGraph
提供了一种 最漂亮
,也可能是最简单的方法来分析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便宜,
if
ing昂贵

如果您有这样的代码:

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()

当条件变为假时:

foo = doSomethingElse # now foo() calls doSomethingElse()
y

PyPy是用python编写的python实现。当然,这意味着它将无限慢地运行代码吗?好吧,不。PyPy实际上使用即时编译器(JIT)运行python程序。

如果您不使用任何外部库(或者您使用的外部库与PyPy兼容),则这是一种(几乎可以肯定)加快程序中重复任务的极其简便的方法。

基本上,JIT可以生成代码,将做什么Python解释器会,但 快,因为它是一个单一的情况下产生的,而不是来处理每一个可能的法律Python表达式。

接下来看哪里

当然,您应该首先考虑的是改进算法和数据结构,并考虑诸如缓存之类的事情,或者甚至是否首先需要做很多事情,但是无论如何:

  • python.org Wiki的此页面提供了许多有关如何加快python代码速度的信息,尽管其中有些过时了。

  • 这是BDFL自己关于优化循环的主题。

即使我从有限的经验中也错过了很多东西,但是这个答案已经足够长了!

这一切都是基于我最近对某些python代码的经验,这些代码 还不够快
,我想再次强调一点,我真的不认为我建议的任何内容实际上是一个好主意,有时但是,您必须…



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5631094.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存