代码跑得慢甩锅Python?手把手教你如何给代码提速30%

互联网
2020
01/13
13:55
IT之家
分享

  Python已经得到了全球程序员的喜爱,但是还是遭到一些人的诟病,原因之一就是认为它运行缓慢。

  其实某个特定程序(无论使用何种编程语言)的运行速度是快还是慢,在很大程度上取决于编写该程序的开发人员自身素质,以及他们编写优化而高效代码的能力。

  Medium上一位小哥就详细讲了讲如何让python提速30%,以此证明代码跑得慢不是python的问题,而是代码本身的问题。

  时序分析

  在开始进行任何优化之前,我们首先需要找出代码的哪些部分使整个程序变慢。有时程序的问题很明显,但是如果你一时不知道问题出在哪里,那么这里有一些可能的选项:

  注意:这是我将用于演示的程序,它将进行指数计算(取自Python文档):

  如果你只能知道整个程序的运行时间,这样就够了,但通常这还远远不够。

  最详细的分析

  另外一个指令是cProfile,但是它提供的信息过于详细了。

  在这里,我们使用cProfile模块和time参数运行测试脚本,以便按内部时间(cumtime)对行进行排序。这给了我们很多信息,你在上面看到的行大约是实际输出的10%。由此可见,exp函数是罪魁祸首,现在我们可以更详细地了解时序和性能分析。

  时序特定功能

  现在我们知道了应当主要关注哪里,我们可能想对运行速度缓慢的函数计时,而不用测量其余的代码。为此,我们可以使用一个简单的装饰器:

  然后可以将此装饰器应用于待测功能,如下所示:

  这给出我们如下输出:

  需要考虑的一件事是我们实际想要测量的时间。时间包提供time.perf_counter和time.process_time两个函数。他们的区别在于perf_counter返回的值,包括你的Python程序进程未运行时的时间,因此它可能会受到计算机负载的影响。另一方面,process_time仅返回用户时间(不包括系统时间),这仅是你的过程时间。

  加速吧!

  让Python程序运行得更快,这部分会很有趣!我不会展示可以解决你的性能问题的技巧和代码,更多地是关于构想和策略的,这些构想和策略在使用时可能会对性能产生巨大影响,在某些情况下,可以将速度提高30%。

  使用内置数据类型

  这一点很明显。内置数据类型非常快,尤其是与我们的自定义类型(例如树或链接列表)相比。这主要是因为内置程序是用C实现的,因此在使用Python进行编码时我们的速度实在无法与之匹敌。

  使用lru_cache缓存/记忆

  我已经在上一篇博客中展示了此内容,但我认为值得用简单的示例来重复它:

  上面的函数使用time.sleep模拟大量计算。第一次使用参数1调用时,它将等待2秒钟,然后才返回结果。再次调用时,结果已经被缓存,因此它将跳过函数的主体并立即返回结果。有关更多实际示例,请参见以前的博客文章。

  使用局部变量

  这与在每个作用域中查找变量的速度有关,因为它不只是使用局部变量还是全局变量。实际上,即使在函数的局部变量(最快),类级属性(例如self.name——较慢)和全局(例如,导入的函数)如time.time(最慢)之间,查找速度实际上也有所不同。

  你可以通过使用看似不必要的分配来提高性能,如下所示:

  使用函数

  这似乎违反直觉,因为调用函数会将更多的东西放到堆栈上,并从函数返回中产生开销,但这与上一点有关。如果仅将整个代码放在一个文件中而不将其放入函数中,则由于全局变量,它的运行速度会慢得多。因此,你可以通过将整个代码包装在main函数中并调用一次来加速代码,如下所示:

  不访问属性

  可能会使你的程序变慢的另一件事是点运算符(.),它在获得对象属性时被使用。此运算符使用__getattribute__触发字典查找,这会在代码中产生额外的开销。那么,我们如何才能真正避免(限制)使用它呢?

  当心字符串

  使用模数(%s)或.format()进行循环运行时,字符串操作可能会变得非常慢。我们有什么更好的选择?根据雷蒙德·海廷格(Raymond Hettinger)最近的推特,我们应该使用的是f字符串,它是最易读,最简洁且最快的方法。根据该推特,这是你可以使用的方法列表——最快到最慢:

  生成器本质上并没有更快,因为它们被允许进行延迟计算,从而节省了内存而不是时间。但是,保存的内存可能会导致你的程序实际运行得更快。这是怎么做到的?如果你有一个很大的数据集,而没有使用生成器(迭代器),那么数据可能会溢出CPU L1缓存,这将大大减慢内存中值的查找速度。

  在性能方面,非常重要的一点是CPU可以将正在处理的所有数据尽可能地保存在缓存中。你可以观看Raymond Hettingers的视频,他在其中提到了这些问题。

  结论

  优化的首要规则是不要优化。但是,如果确实需要,那么我希望上面这些技巧可以帮助你。但是,在优化代码时要小心,因为它可能最终使你的代码难以阅读,因此难以维护,这可能超过优化的好处。

THE END
免责声明:本文系转载,版权归原作者所有;旨在传递信息,不代表一点科技的观点和立场。
为你推荐
猜你喜欢

同城获客系统怎么甄别服务商?拓氪科技 AIGEO 引擎方案靠谱吗

同城流量,正成为本地实体、区域B端企业稳定客源的核心基本盘。但渠道分散、链路割裂、数据掺水、代运营溢价等痛点持续推高获客成本。艾瑞咨询调研数据显示,超六成本地企业采购营销服务时,难以区分技术工具供应商

科技 AI

1周前

海外 GEO 优化该怎么采购避坑,朝闻通能提供哪些落地解决方案?

生成式大模型正在重塑全球商业信息获取路径,传统海外SEO依靠关键词排名、外链铺量的投放逻辑,价值边界持续收窄。海外GEO优化以E-E-A-T可信信源建设为底层框架,核心目标是沉淀能够被海外主流大模型识

1周前

企业做户外广告投放怎么避坑,传播易的资源与优势有哪些

线上流量竞争加剧、获客成本持续走高,户外媒体依托场景沉浸式、低干扰、强到达的传播特质,重新成为企业品牌建设、区域获客的重要渠道。从企业采购视角看,户外广告投放长期存在资源分散、报价信息不透明、多层转包

企业 传播易

1周前

拓氪科技外贸获客系统有哪些落地优势?

一、行业现状与投放价值全球B2B采购决策正加速向AI信息检索迁移,国内出海企业的外贸获客底层逻辑迎来结构性变革。传统获客渠道,如B2B平台竞价、线下海外展会、独立站传统SEO等,普遍显现边际效益递减:

科技

3周前

企业采购品牌推广引流服务,朝闻通能解决哪些投放痛点?

一、行业现状与投放价值流量成本持续走高,品牌推广引流已经脱离单纯稿件发布、单次广告曝光的浅层阶段,转向品牌公信力搭建、目标人群精准触达、传播效果可追溯的全域传播体系。艾瑞咨询监测数据显示,国内企业市场

企业 品牌

3周前

选择传播易 GEO 优化系统,能解决 AI 检索信源难题吗?

生成式大模型正在重构品牌信息触达的底层逻辑。传统SEO的核心目标是争夺搜索引擎页面关键词排名,流量获取高度依赖网页排序;而GEO生成式引擎优化,核心是打造符合E-E-A-T标准的品牌可信语料资产,提升

传播易 AI

3周前