1. 7种检测python程序运行时间、CPU和内存占用的方法
1. 使用装饰器来衡量函数执行时间
有一个简单方法,那就是定义一个装饰器来测量函数的执行时间,并输出结果:
import time
from functoolsimport wraps
import random
def fn_timer(function):
@wraps(function)
def function_timer(*args, **kwargs):
t0= time.time()
result= function(*args, **kwargs)
t1= time.time()
print("Total time running %s: %s seconds" %
(function.__name__, str(t1- t0))
)
return result
return function_timer
@fn_timer
def random_sort(n):
return sorted([random.random() for i in range(n)])
if __name__== "__main__":
random_sort(2000000)
输出:Total time running random_sort: 0.6598007678985596 seconds
使用方式的话,就是在要监控的函数定义上面加上 @fn_timer 就行了
或者
# 可监控程序运行时间
import time
import random
def clock(func):
def wrapper(*args, **kwargs):
start_time= time.time()
result= func(*args, **kwargs)
end_time= time.time()
print("共耗时: %s秒" % round(end_time- start_time, 5))
return result
return wrapper
@clock
def random_sort(n):
return sorted([random.random() for i in range(n)])
if __name__== "__main__":
random_sort(2000000)
输出结果:共耗时: 0.65634秒
2. 使用timeit模块
另一种方法是使用timeit模块,用来计算平均时间消耗。
执行下面的脚本可以运行该模块。
这里的timing_functions是Python脚本文件名称。
在输出的末尾,可以看到以下结果:4 loops, best of 5: 2.08 sec per loop
这表示测试了4次,平均每次测试重复5次,最好的测试结果是2.08秒。
如果不指定测试或重复次数,默认值为10次测试,每次重复5次。
3. 使用Unix系统中的time命令
然而,装饰器和timeit都是基于Python的。在外部环境测试Python时,unix time实用工具就非常有用。
运行time实用工具:
输出结果为:
Total time running random_sort: 1.3931210041 seconds
real 1.49
user 1.40
sys 0.08
第一行来自预定义的装饰器,其他三行为:
real表示的是执行脚本的总时间
user表示的是执行脚本消耗的CPU时间。
sys表示的是执行内核函数消耗的时间。
注意:根据维基网络的定义,内核是一个计算机程序,用来管理软件的输入输出,并将其翻译成CPU和其他计算机中的电子设备能够执行的数据处理指令。
因此,Real执行时间和User+Sys执行时间的差就是消耗在输入/输出和系统执行其他任务时消耗的时间。
4. 使用cProfile模块
5. 使用line_profiler模块
6. 使用memory_profiler模块
7. 使用guppy包
2. 电脑c盘内存只有2G了,安装python老提示出错,python安装出错跟这个有关系吗
c盘那个不叫内存,叫硬盘,硬盘只剩余2g太少了
3. 安装python时出现0x60ef5eaa指令引用的0x00000020内存,该内从不能为read 我应该怎么办
你好:
很多网友出现的蓝屏(0x00390b67指令引用的0x80391510内存不能为read )的问题,总结出了以下解决办法,看看下面您的电脑是哪方面出的问题,只有对症下药问题才能解决。这个问题的出现主要有几个方面:
1.如果使用盗版系统,有可能会出现这样的问题,建议:使用正版。
2.如果对电脑没有影响或偶尔出现不用管它,重启电脑会自动消失。
3.病毒引起的,升级杀毒软件,对电脑全盘杀毒。
4.硬件上的原因,主要是内存条不兼容引起的,必要时更换内存。
5.系统或其它软件引起的,检查电脑年、月、日是否正确。
6.驱动不稳定,重新安装或及时更新驱动。同时使用优化大师、360、鲁大师清理垃圾文件也会出现该问题。
7.打开或关闭IE、QQ、游戏、播放器等出现该内存不能为read或written,首先想到的可能就是这款软件的问题。
8.如果您使用IE8,打补丁后,很多网友反映不太稳定。最简单的解决办法就是:下载更换其它浏览器。比如:360安全浏览器、世界之窗浏览器、傲游等.
9.系统本身有问题,及时安装官方发行的补丁,必要时重装系统
10.某个软件出现的问题,这里主要是看看开机时运行的软件,用360等检查开机运行的软件,把不必要运行的软件都去掉
11.软件冲突,卸载有问题的软件。(比如:安装或运行时出现,升级、打补丁、更换其它版本或卸载问题才能解决。
12.下面的处理方法可以试试:如果不行,只有恢复或重装系统了.
13.试用命令排除
开始-运行- 输入cmd-- 回车,在命令提示符下输入下面命令
for %1 in (%windir%\system32\*.dll) do regsvr32.exe /s %1回车。
完成后,在输入下面的
for %i in (%windir%\system32\*.ocx) do regsvr32.exe /s %i 回车。
如果怕输入错误,可以复制这两条指令,然后在命令提示符后击鼠标右键,打“粘贴”,回车,耐心等待,直到屏幕滚动停止为止。重启电脑.
14.运行regedit进入注册表, 在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks 下,应该只有一个正常的键值{AEB6717E-7E19-11d0-97EE-00C04FD91972}, 将其他的删除。【如果还有一个(默认)不用管它,一般它为空。】
15.如果上面的方法都不能解决,从网上下载一个“read修复工具”修复一下试试 。
如果有不明之处,请参考:http://hi..com/qiaowenlong/blog/item/eb6f7bdb2b25ce61d1164ee0.html
复制此答案的朋友请自重!!!
4. 为什么电脑内存很大,python跑程序时却说memory resource exhauted
要破这个东西,要先破你的算法。 先别说破这个词了。 梳理你的算法,避免三重循环, 避免大量使用字典的多次嵌套。 显然你的数据量巨大。还用这么耗内存,耗CPU的算法。只有算法改良了才能解决这个问题。即使给你C语编程,你都能把内存用光了。...
5. Python如何进行内存管理
Python是如何进行内存管理的?
答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制。
一、对象的引用计数机制
Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。
引用计数增加的情况:
1,一个对象分配一个新名称
2,将其放入一个容器中(如列表、元组或字典)
引用计数减少的情况:
1,使用del语句对对象别名显示的销毁
2,引用超出作用域或被重新赋值
Sys.getrefcount( )函数可以获得对象的当前引用计数
多数情况下,引用计数比你猜测得要大得多。对于不可变数据(如数字和字符串),解释器会在程序的不同部分共享内存,以便节约内存。
相关推荐:《Python视频教程》
二、垃圾回收
1,当一个对象的引用计数归零时,它将被垃圾收集机制处理掉。
2,当两个对象a和b相互引用时,del语句可以减少a和b的引用计数,并销毁用于引用底层对象的名称。然而由于每个对象都包含一个对其他对象的应用,因此引用计数不会归零,对象也不会销毁。(从而导致内存泄露)。为解决这一问题,解释器会定期执行一个循环检测器,搜索不可访问对象的循环并删除它们。
三、内存池机制
Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。
1,Pymalloc机制。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。
2,Python中所有小于256个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的malloc。
3,对于Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。
6. BAT面试题28:Python是如何进行内存管理的
Python的内存管理,一般从以下三个方面来说:
1)对象的引用计数机制(四增五减)
2)垃圾回收机制(手动自动,分代回收)
3)内存池机制(大m小p)
1)对象的引用计数机制
要保持追踪内存中的对象,Python使用了引用计数这一简单的技术。sys.getrefcount(a)可以查看a对象的引用计数,但是比正常计数大1,因为调用函数的时候传入a,这会让a的引用计数+1
2)垃圾回收机制
吃太多,总会变胖,Python也是这样。当Python中的对象越来越多,它们将占据越来越大的内存。不过你不用太担心Python的体形,它会在适当的时候“减肥”,启动垃圾回收(garbage
collection),将没用的对象清除
从基本原理上,当Python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了
比如某个新建对象,它被分配给某个引用,对象的引用计数变为1。如果引用被删除,对象的引用计数为0,那么该对象就可以被垃圾回收。
然而,减肥是个昂贵而费力的事情。垃圾回收时,Python不能进行其它的任务。频繁的垃圾回收将大大降低Python的工作效率。如果内存中的对象不多,就没有必要总启动垃圾回收。
所以,Python只会在特定条件下,自动启动垃圾回收。当Python运行时,会记录其中分配对象(object
allocation)和取消分配对象(object deallocation)的次数。当两者的差值高于某个阈值时,垃圾回收才会启动。
我们可以通过gc模块的get_threshold()方法,查看该阈值。
3)内存池机制
Python中有分为大内存和小内存:(256K为界限分大小内存)
1、大内存使用malloc进行分配
2、小内存使用内存池进行分配
python中的内存管理机制都有两套实现,一套是针对小对象,就是大小小于256K时,pymalloc会在内存池中申请内存空间;当大于256K时,则会直接执行系统的malloc的行为来申请内存空间。
7. Python 的内存管理机制
Python采用自动内存管理,即Python会自动进行垃圾回收,不需要像C、C++语言一样需要程序员手动释放内存,手动释放可以做到实时性,但是存在内存泄露、空指针等风险。
Python自动垃圾回收也有自己的优点和缺点:优点:
缺点:
Python的垃圾回收机制采用 以引用计数法为主,分代回收为辅 的策略。
先聊引用计数法,Python中每个对象都有一个核心的结构体,如下
一个对象被创建时,引用计数值为1,当一个变量引用一个对象时,该对象的引用计数ob_refcnt就加一,当一个变量不再引用一个对象时,该对象的引用计数ob_refcnt就减一,Python判断是否回收一个对象,会将该对象的引用计数值ob_refcnt减一判断结果是否等于0,如果等于0就回收,如果不等于0就不回收,如下:
一个对象在以下三种情况下引用计数会增加:
一个对象在以下三种情况引用计数会减少:
验证案例:
运行结果:
事实上,关于垃圾回收的测试,最好在终端环境下测试,比如整数257,它在PyCharm中用下面的测试代码打印出来的结果是4,而如果在终端环境下打印出来的结果是2。这是因为终端代表的是原始的Python环境,而PyCharm等IDE做了一些特殊处理,在Python原始环境中,整数缓存的范围是在 [-5, 256] 的双闭合区间内,而PyCharm做了特殊处理之后,PyCharm整数缓存的范围变成了 [-5, 无穷大],但我们必须以终端的测试结果为主,因为它代表的是原始的Python环境,并且代码最终也都是要发布到终端运行的。
好,那么回到终端,我们来看两种特殊情况
前面学习过了,整数缓存的范围是在 [-5, 256] 之间,这些整数对象在程序加载完全就已经驻留在内存之中,并且直到程序结束退出才会释放占有的内存,测试案例如下:
如果字符串的内容只由字母、数字、下划线构成,那么它只会创建一个对象驻留在内存中,否则,每创建一次都是一个新的对象。
引用计数法有缺陷,它无法解决循环引用问题,即A对象引用了B对象,B对象又引用了A对象,这种情况下,A、B两个对象都无法通过引用计数法来进行回收,有一种解决方法是程序运行结束退出时进行回收,代码如下:
前面讲过,Python垃圾回收机制的策略是 以引用计数法为主,以分代回收为辅 。分代回收就是为了解决循环引用问题的。
Python采用分代来管理对象的生命周期:第0代、第1代、第2代,当一个对象被创建时,会被分配到第一代,默认情况下,当第0代的对象达到700个时,就会对处于第0代的对象进行检测和回收,将存在循环引用的对象释放内存,经过垃圾回收后,第0代中存活的对象会被分配为第1代,同样,当第1代的对象个数达到10个时,也会对第1代的对象进行检测和回收,将存在循环引用的对象释放内存,经过垃圾回收后,第1代中存活的对象会被分配为第2代,同样,当第二代的对象个数达到10个时,也会对第2代的对象进行检测和回收,将存在循环引用的对象释放内存。Python就是通过这样一种策略来解决对象之间的循环引用问题的。
测试案例:
运行结果:
如上面的运行结果,当第一代中对象的个数达到699个即将突破临界值700时(在打印699之前就已经回收了,所以看不到698和699)进行了垃圾回收,回收掉了循环引用的对象。
第一代、第二代、第三代分代回收都是有临界值的,这个临界值可以通过调用 gc.get_threshold 方法查看,如下:
当然,如果对默认临界值不满意,也可以调用 gc.set_threshold 方法来自定义临界值,如下:
最后,简单列出两个gc的其它方法,了解一下,但禁止在程序代码中使用
以上就是对Python垃圾回收的简单介绍,当然,深入研究肯定不止这些内容,目前,了解到这个程度也足够了。
8. 关于Python一直提示IndexError: list index out of range是怎么回事
”IndexError: list index out of range”这种错误一般有两种情况:
第一种可能情况:list[index], index超出范围,也就是常说的数组越界。
第二种可能情况:list是一个空的,没有一个元素,进行list[0]就会出现该错误,在爬虫问题中很常见,比如有个列表爬去下来为空,统一处理就会报错。
(8)python内存提示扩展阅读:
异常处理特点:
1.在应用程序遇到异常情况(如被零除情况或内存不足警告)时,就会产生异常。
2.发生异常时,控制流立即跳转到关联的异常处理程序(如果存在)。
3.如果给定异常没有异常处理程序,则程序将停止执行,并显示一条错误信息。
4.可能导致异常的操作通过 try 关键字来执行。
5.异常处理程序是在异常发生时执行的代码块。在 C# 中,catch 关键字用于定义异常处理程序。
6.程序可以使用 throw 关键字显式地引发异常。
7.异常对象包含有关错误的详细信息,其中包括调用堆栈的状态以及有关错误的文本说明。
8.即使引发了异常,finally 块中的代码也会执行,从而使程序可以释放资源。
参考资料:网络——异常处理
9. python的内存问题该这么解决
1.没有开gc,或者gc设为debug状态,导致交叉引用没有被回收调
2.如果一个数据在逻辑上不应该存在,但是因为代码上没有做相关清除操作,导致他还存在,也是一种泄漏
举个栗子,例如我要记录最近50天的某个基金的日化收益率,定义一个全局的字典global_dict,运行了一个脚本进行计算,没10分钟算一次,但是我没有进行clear操作,每次的计算只是单纯的赋值dict[date] = rate,按理来说dict["五十天前"]的收益率都是不需要的,就是一种泄漏。
3.这种情况出现在python3.4之前,因为3.4已经修复了,是这样的,如果一个类定义了__del__,并且该类存在循环引用的情况,这时候gc就会把这个类放在gc.garbage当中,不会去做回收,可以说是跳出了分代回收的机制,但是3.4之后的版本就没有这种情况,会把他回收调。
10. python 中的out of memory是怎么回事,内存不够吗
这不是你电脑内存大小的问题,
在编程中,如果在一个域中输入的数据超过了它的要求就会引发数据溢出问题。
缓冲区溢出好比是将十磅的糖放进一个只能装五磅的容器里。一旦该容器放满了,余下的部分就溢出在柜台和地板上,弄得一团糟。由于计算机程序的编写者写了一些编码,但是这些编码没有对目的区域或缓冲区——五磅的容器——做适当的检查,看它们是否够大,能否完全装入新的内容——十磅的糖,结果可能造成缓冲区溢出的产生。如果打算被放进新地方的数据不适合,溢得到处都是,该数据也会制造很多麻烦。但是,如果缓冲区仅仅溢出,这只是一个问题。到此时为止,它还没有破坏性。当糖溢出时,柜台被盖住。可以把糖擦掉或用吸尘器吸走,还柜台本来面貌。与之相对的是,当缓冲区溢出时,过剩的信息覆盖的是计算机内存中以前的内容。除非这些被覆盖的内容被保存或能够恢复,否则就会永远丢失。
具体你可以看下边的资料。