我的编程空间,编程开发者的网络收藏夹
学习永远不晚

优化python执行效率

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

优化python执行效率

开始优化前,写一个高级测试来证明原来代码很慢。你可能需要采用一些最小值数据集来复现它足够慢。通常一两个显示运行时秒的程序就足够处理一些改进的地方了。


有一些基础测试来保证你的优化没有改变原有代码的行为也是很必要的。你也能够在很多次运行测试来优化代码的时候稍微修改这些测试的基准。


那么现在,我们来来看看优化工具把。

简单的计时器


计时器很简单,这是一个最灵活的记录执行时间的方法。你可以把它放到任何地方并且副作用很小。运行你自己的计时器非常简单,并且你可以将其定制,使它以你期望的方式工作。例如,你个简单的计时器如下:

import time    

def timefunc(f):  

def f_timer(*args, **kwargs):  

 start = time.time()   result = f(*args, **kwargs)  

 end = time.time()   print f.__name__, 'took', end - start, 'time'  return result  return f_timer    def get_number():  for x in xrange(5000000):   yield x    @timefuncdef expensive_function():  for x in get_number():   i = x ^ x ^ x  return 'some result!'   # prints "expensive_function took 0.72583088875 seconds" result = expensive_function() 


当然,你可以用上下文管理来让它功能更加强大,添加一些检查点或者一些其他的功能:

 import time    class timewith():  def __init__(self, name=''):   self.name = name   self.start = time.time()     @property def elapsed(self):   return time.time() - self.start     def checkpoint(self, name=''):   print '{timer} {checkpoint} took {elapsed} seconds'.format(    timer=self.name,    checkpoint=name,    elapsed=self.elapsed,   ).strip()     def __enter__(self):   return self    def __exit__(self, type, value, traceback):   self.checkpoint('finished')   pass   def get_number():  for x in xrange(5000000):   yield x    def expensive_function():  for x in get_number():   i = x ^ x ^ x  return 'some result!'   # prints something like: # fancy thing done with something took 0.582462072372 seconds # fancy thing done with something else took 1.75355315208 seconds # fancy thing finished took 1.7535982132 seconds with timewith('fancy thing') as timer:  expensive_function()  timer.checkpoint('done with something')  expensive_function()  expensive_function()  timer.checkpoint('done with something else')    # or directly timer = timewith('fancy thing') expensive_function() timer.checkpoint('done with something') 


计时器还需要你做一些挖掘。包装一些更高级的函数,并且确定瓶颈在哪,然后深入的函数里,能够不停的重现。当你发现一些不合适的代码,修复它,然后测试一遍以确认它被修复了。


一些小技巧:不要忘了好用的timeit模块!它对小块代码做基准测试而不是实际调查更加有用。


    Timer 优点:很容易理解和实现。也非常容易在修改后进行比较。对于很多语言都适用。 

    Timer 缺点:有时候对于非常复杂的代码有点过于简单,你可能会花更多时间放置或移动引用代码而不是修复问题! 

内建优化器


启用内建的优化器就像是用一门大炮。它非常强大,但是有点不太好用,使用和解释起来比较复杂。


你可以了解更多关于profile模块的东西,但是它的基础是非常简单的:你能够启用和禁用优化器,而且它能打印所有的函数调用和执行时间。它能给你编译和打印出输出。一个简单的装饰器如下:

 import cProfile    def do_cprofile(func):  def profiled_func(*args, **kwargs):   profile = cProfile.Profile()   try:    profile.enable()    result = func(*args, **kwargs)    profile.disable()    return result   finally:    profile.print_stats()  return profiled_func    def get_number():  for x in xrange(5000000):   yield x    @do_cprofiledef expensive_function():  for x in get_number():   i = x ^ x ^ x  return 'some result!'   # perform profiling result = expensive_function() 


在上面代码的情况下,你应该看到有些东西在终端打印出来,打印的内容如下:

5000003 function calls in 1.626 seconds     Ordered by: standard name     ncalls tottime percall cumtime percall filename:lineno(function)  5000001 0.571 0.000 0.571 0.000 timers.py:92(get_number)   1 1.055 1.055 1.626 1.626 timers.py:96(expensive_function)   1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 


你可以看到,它给出了不同函数的调用次数,但它遗漏了一些关键的信息:是哪个函数让运行这么慢?


可是,这对于基础优化来说是个好的开始。有时候甚至能用更少的精力找到解决方案。我经常用它来在深入挖掘究竟是哪个函数慢或者调用次数过多之前来调试程序。


    内建优点:没有额外的依赖并且非常快。对于快速的高等级检查非常有用。 

    内建缺点:信息相对有限,需要进一步的调试;报告有点不太直接,尤其是对于复杂的代码。 

Line Profiler


如果内建的优化器是一门大炮,那么line profiler可以看作是一门离子加农炮。它非常的重量级和强大。


在这个例子里,我们会用非常棒的line_profiler库。为了容易使用,我们会再次用装饰器包装一下,这种简单的方法也可以防止把它放在生产代码里。

 

try:  from line_profiler import LineProfiler     def do_profile(follow=[]):   def inner(func):    def profiled_func(*args, **kwargs):     try:      profiler = LineProfiler()      profiler.add_function(func)      for f in follow:       profiler.add_function(f)      profiler.enable_by_count()      return func(*args, **kwargs)     finally:      profiler.print_stats()    return profiled_func   return inner    except ImportError:  def do_profile(follow=[]):   "Helpful if you accidentally leave in production!"  def inner(func):    def nothing(*args, **kwargs):     return func(*args, **kwargs)    return nothing   return inner    def get_number():  for x in xrange(5000000):   yield x    @do_profile(follow=[get_number]) def expensive_function():  for x in get_number():   i = x ^ x ^ x  return 'some result!'   result = expensive_function() 


如果你运行上面的代码,你就可以看到一下的报告:

 Timer unit: 1e-06 s    File: test.py Function: get_number at line 43Total time: 4.44195 s    Line #  Hits   Time Per Hit % Time Line Contents ============================================================== 43           def get_number():  44 5000001  2223313  0.4  50.1  for x in xrange(5000000):  45 5000000  2218638  0.4  49.9   yield x    File: test.py Function: expensive_function at line 47Total time: 16.828 s    Line #  Hits   Time Per Hit % Time Line Contents ============================================================== 47           def expensive_function():  48 5000001  14090530  2.8  83.7  for x in get_number():  49 5000000  2737480  0.5  16.3   i = x ^ x ^ x  50   1   0  0.0  0.0  return 'some result!' 


你可以看到,有一个非常详细的报告,能让你完全洞悉代码运行的情况。不想内建的cProfiler,它能计算话在语言核心特性的时间,比如循环和导入并且给出在不同的行花费的时间。


这些细节能让我们更容易理解函数内部。如果你在研究某个第三方库,你可以直接将其导入并加上装饰器来分析它。


一些小技巧:只装饰你的测试函数并将问题函数作为接下来的参数。


     Line Profiler 优点:有非常直接和详细的报告。能够追踪第三方库里的函数。 

     Line Profiler 缺点:因为它会让代码比真正运行时慢很多,所以不要用它来做基准测试。这是额外的需求。 

总结和最佳实践


你应该用更简单的工具来对测试用例进行根本的检查,并且用更慢但能显示更多细节的line_profiler来深入到函数内部。


九成情况下,你可能会发现在一个函数里循环调用或一个错误的数据结构消耗了90%的时间。一些调整工具是非常适合你的。


如果你仍然觉得这太慢,而是用一些你自己的秘密武器,如比较属性访问技术或调整平衡检查技术。你也可以用如下的方法:


1.忍受缓慢或者缓存它们


2.重新思考整个实现


3.更多使用优化的数据结构


4.写一个C扩展


注意了,优化代码是种罪恶的快感!用合适的方法来为你的Python代码加速很有意思,但是注意不要破坏了本身的逻辑。可读的代码比运行速度更重要。先把它缓存起来再进行优化其实更好。



免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

优化python执行效率

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

优化python执行效率

开始优化前,写一个高级测试来证明原来代码很慢。你可能需要采用一些最小值数据集来复现它足够慢。通常一两个显示运行时秒的程序就足够处理一些改进的地方了。有一些基础测试来保证你的优化没有改变原有代码的行为也是很必要的。你也能够在很多次运行测试来优
2023-01-31

优化Python脚本在Linux上的执行效率

标题:优化Python脚本在Linux上的执行效率引言:Python是一种高级动态编程语言,以其简单易学、灵活性和强大的库支持而广泛受到开发者的欢迎。然而,Python在执行效率方面相对较慢,尤其是涉及大量数据处理或计算密集型任务时。本文将
2023-10-22

Golang 进程调度:优化并发执行效率

go 进程调度使用协作式算法,优化方法包括:尽可能使用轻量级协程合理分配协程避免阻塞操作使用锁和同步原语Go 进程调度:优化并发执行效率在 Go 中,进程调度是决定在并发环境中如何分配 CPU 时间给协程的过程。高效的进程调度对于最大化应
Golang 进程调度:优化并发执行效率
2024-04-03

PHP开发中如何优化代码执行效率

一、使用合适的数据结构在PHP开发中,使用合适的数据结构可以大大提高代码执行效率。以下是一些常用的数据结构及其优化方法:数组(Array)优化:尽量使用多维数组或关联数组,而不是一维数组,可以提高查找和插入的效率。在大数据量的情况下,考虑使
2023-10-21

提高Go语言切片性能,优化代码执行效率

本篇文章向大家介绍《提高Go语言切片性能,优化代码执行效率》,主要包括,具有一定的参考价值,需要的朋友可以参考一下。优化Go语言切片的性能,提升代码效率在Go编程中,切片(slice)是一种动态数组类型,能够方便地处理变长数组,是Go语言中
提高Go语言切片性能,优化代码执行效率
2024-04-04

如何优化PHP开发中的代码执行效率和性能

随着互联网的高速发展,PHP作为一门扎根于网络开发的脚本语言,被广泛应用于网页开发、服务器编程等领域。然而,PHP代码执行效率和性能问题一直是开发者们面临的挑战。在本文中,我们将探讨如何通过优化PHP代码来提高执行效率和性能,同时给出具体的
2023-10-21

Java switch 执行效率如何评估?(java switch执行效率怎样评估)

在Java编程中,switch语句是一种常用的控制结构,用于根据不同的条件执行不同的代码块。然而,对于switch语句的执行效率,很多开发者可能存在一些疑问。本文将详细介绍如何评估Javaswitch语句的执行效率,并提供一些优化建议。一、swi
Java switch 执行效率如何评估?(java switch执行效率怎样评估)
Java2024-12-19

如何通过优化Ruby循环结构提升代码执行效率

Ruby循环结构如何提高执行效率在编写代码时,我们经常需要使用循环结构来处理大量数据。然而,如果循环结构使用不当,可能会导致程序运行缓慢甚至崩溃。因此,了解如何在Ruby中使用循环结构并提高其执行效率是非常重要的。本文将介绍一些技巧和最佳实践,帮助您优化您的Ruby代码,
如何通过优化Ruby循环结构提升代码执行效率
ruby2024-12-14

C++ 性能优化指南:探索提高代码执行效率的秘诀

c++++ 性能优化涉及多种技术,包括:1. 避免动态分配;2. 使用编译器优化标志;3. 选择优化数据结构;4. 应用缓存;5. 并行编程。优化实战案例展示了如何在整数数组中查找最长上升子序列时应用这些技术,将算法效率从 o(n^2) 提
C++ 性能优化指南:探索提高代码执行效率的秘诀
2024-05-23

探索Ruby方法调用的优化技巧:提升代码执行效率

Ruby方法调用提升指南在编程的世界里,Ruby语言以其简洁明了的语法和强大的功能而广受欢迎。然而,尽管Ruby提供了许多方便的方法来简化代码,但有时我们仍然需要手动编写复杂的方法调用,这时就需要掌握一些技巧来提升我们的编程效率。本文将介绍一些实用的Ruby方法调用技巧,帮助你
探索Ruby方法调用的优化技巧:提升代码执行效率
ruby2024-12-14

理解Java虚拟机(JVM):优化代码执行效率的内部机制

本文将深入理解JVM的内部机制,以及如何通过优化代码执行提高程序的性能。
虚拟机程序2024-11-30

python多线程效率低如何优化

有几种方法可以优化Python多线程的效率:使用Python的多进程模块:由于Python的全局解释器锁(GIL)限制了多线程的并发性,因此使用多进程可以绕过GIL的限制,提高并发性能。使用线程池:Python的标准库提供了线程池的实现,可
2023-10-25

提升Python的执行效率的技巧有哪些

今天小编给大家分享一下提升Python的执行效率的技巧有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。开始之前小伙伴先可
2023-07-06

python中怎么优化ChainMap的调用效率

python中怎么优化ChainMap的调用效率?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。python的五大特点是什么python的五大特点:1.简单易学,
2023-06-14

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录