iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >如何优化Python占用的内存
  • 931
分享到

如何优化Python占用的内存

内存Python 2023-01-31 08:01:10 931人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

概述 如果程序处理的数据比较多、比较复杂,那么在程序运行的时候,会占用大量的内存,当内存占用到达一定的数值,程序就有可能被操作系统终止,特别是在限制程序所使用的内存大小的场景,更容易发生问题。下面我就给出几个优化python占用内存的几个

概述

如果程序处理的数据比较多、比较复杂,那么在程序运行的时候,会占用大量的内存,当内存占用到达一定的数值,程序就有可能被操作系统终止,特别是在限制程序所使用的内存大小的场景,更容易发生问题。下面我就给出几个优化python占用内存的几个方法。

说明:以下代码运行在python3

举个栗子

我们举个简单的场景,使用Python存储一个三维坐标数据,x,y,z。

Dict

使用Python内置的数据结构Dict来实现上述例子的需求很简单。

>>> ob = {'x':1, 'y':2, 'z':3}
>>> x = ob['x']
>>> ob['y'] = y

查看以下ob这个对象占用的内存大小:

>>> print(sys.getsizeof(ob))
240

简单的三个整数,占用的内存还真不少,想象以下,如果有大量的这样的数据要存储,会占用更大的内存。

数据量 占用内存大小
1 000 000 240 Mb
10 000 000 2.40 Gb
100 000 000 24 Gb

Class

对于喜欢面向对象编程程序员来说,更喜欢把数据包在一个class里。使用class使用同样需求:

class Point:
    #
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

>>> ob = Point(1,2,3)

class的数据结构和Dict区别就很大了,我们来看看这种情况下占用内存的情况:

字段 占用内存
PyGC_Head 24
PyObject_HEAD 16
_weakref_ 8
_dict_ 8
TOTAL 56

关于 __weakref__(弱引用)可以查看这个文档, 对象的__dict__中存储了一些self.xxx的一些东西。从Python 3.3开始,key使用了共享内存存储, 减少了RAM中实例跟踪的大小。

>>> print(sys.getsizeof(ob), sys.getsizeof(ob.__dict__)) 
56 112
数据量 占用内存
1 000 000 168 Mb
10 000 000 1.68 Gb
100 000 000 16.8 Gb

可以看到内存占用量,class比dict少了一些,但这远远不够。

_slots_

从class的内存占用分布上,我们可以发现,通过消除__dict__和_weakref__,可以显着减少RAM中类实例的大小,我们可以通过使用__slots__来达到这个目的。

class Point:
    __slots__ = 'x', 'y', 'z'

    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

>>> ob = Point(1,2,3)
>>> print(sys.getsizeof(ob))
64

可以看到内存占用显著的减少了

字段 内存占用
PyGC_Head 24
PyObject_HEAD 16
x 8
y 8
z 8
TOTAL 64
数据量 占用内存
1 000 000 64Mb
10 000 000 640Mb
100 000 000 6.4Gb

默认情况下,Python的新式类和经典类的实例都有一个dict来存储实例的属性。这在一般情况下还不错,而且非常灵活,乃至在程序中可以随意设置新的属性。但是,对一些在”编译”前就知道有几个固定属性的小class来说,这个dict就有点浪费内存了。

当需要创建大量实例的时候,这个问题变得尤为突出。一种解决方法是在新式类中定义一个__slots__属性。

__slots__声明中包含若干实例变量,并为每个实例预留恰好足够的空间来保存每个变量;这样Python就不会再使用dict,从而节省空间。

那么用slot就是非非常那个有必要吗?使用__slots__也是有副作用的:

  1. 每个继承的子类都要重新定义一遍__slots__
  2. 实例只能包含哪些在__slots__定义的属性,这对写程序的灵活性有影响,比如你由于某个原因新网给instance设置一个新的属性,比如instance.a = 1, 但是由于a不在__slots__里面就直接报错了,你得不断地去修改__slots__或者用其他方法迂回的解决
  3. 实例不能有弱引用(weakref)目标,否则要记得把__weakref__放进__slots__

最后,namedlist和attrs提供了自动创建带__slot__的类,感兴趣的可以试试看。

Tuple

Python还有一个内置类型元组,用于表示不可变数据结构。 元组是固定的结构或记录,但没有字段名称。 对于字段访问,使用字段索引。 在创建元组实例时,元组字段一次性与值对象关联:

>>> ob = (1,2,3)
>>> x = ob[0]
>>> ob[1] = y # ERROR

元组的示例很简洁:

>>> print(sys.getsizeof(ob))
72

可以看只比__slot__多8byte:

字段 占用内存(bytes)
PyGC_Head 24
PyObject_HEAD 16
ob_size 8
[0] 8
[1] 8
[2] 8
TOTAL 72

Namedtuple

通过namedtuple我们也可以实现通过key值来访问tuple里的元素:

Point = namedtuple('Point', ('x', 'y', 'z'))

它创建了一个元组的子类,其中定义了用于按名称访问字段的描述符。 对于我们的例子,它看起来像这样:

class Point(tuple):
     #
     @property
     def _get_x(self):
         return self[0]
     @property
     def _get_y(self):
         return self[1]
     @property
     def _get_y(self):
         return self[2]
     #
     def __new__(cls, x, y, z):
         return tuple.__new__(cls, (x, y, z))

此类的所有实例都具有与元组相同的内存占用。 大量实例会留下稍大的内存占用:

数据量 内存占用
1 000 000 72 Mb
10 000 000 720 Mb
100 000 000 7.2 Gb

Recordclass

python的第三方库recordclassd提供了一个数据结构recordclass.mutabletuple,它几乎和内置tuple数据结构一致,但是占用更少的内存。

 >>> Point = recordclass('Point', ('x', 'y', 'z'))
 >>> ob = Point(1, 2, 3)

实例化以后,只少了PyGC_Head:

字段 占用内存
PyObject_HEAD 16
ob_size 8
x 8
y 8
y 8
TOTAL 48

到此,我们可以看到,和__slot__比,又进一步缩小了内存占用:

数据量 内存占用
1 000 000 48 Mb
10 000 000 480 Mb
100 000 000 4.8 Gb

Dataobject

recordclass提供了另外一个解决方法:在内存中使用与__slots__类相同的存储结构,但不参与循环垃圾收集机制。通过recordclass.make_dataclass可以创建出这样的实例:

>>> Point = make_dataclass('Point', ('x', 'y', 'z'))

另外一个方法是继承自dataobject

class Point(dataobject):
    x:int
    y:int
    z:int

以这种方式创建的类将创建不参与循环垃圾收集机制的实例。 内存中实例的结构与__slots__的情况相同,但没有PyGC_Head:

字段 内存占用(bytes)
PyObject_HEAD 16
x 8
y 8
y 8
TOTAL 40
>>> ob = Point(1,2,3)
>>> print(sys.getsizeof(ob))
40

要访问这些字段,还使用特殊描述符通过其从对象开头的偏移量来访问字段,这些对象位于类字典中:

mappingproxy({'__new__': <staticmethod at 0x7f203c4e6be0>,
              .......................................
              'x': <recordclass.dataobject.dataslotgetset at 0x7f203c55c690>,
              'y': <recordclass.dataobject.dataslotgetset at 0x7f203c55c670>,
              'z': <recordclass.dataobject.dataslotgetset at 0x7f203c55c410>})
数据量 内存占用
1 000 000 40 Mb
10 000 000 400 Mb
100 000 000 4.0 Gb

Cython

有一种方法基于Cython的使用。 它的优点是字段可以采用C语言原子类型的值。例如:

cdef class Python:
    cdef public int x, y, z

 def __init__(self, x, y, z):
      self.x = x
      self.y = y
      self.z = z

这种情况下,占用的内存更小:

>>> ob = Point(1,2,3)
>>> print(sys.getsizeof(ob))
32

内存结构分布如下:

字段 内存占用(bytes)
PyObject_HEAD 16
x 4
y 4
y 4
пусто 4
TOTAL 32
数据量 内存占用
1 000 000 32 Mb
10 000 000 320 Mb
100 000 000 3.2 Gb

但是,从Python代码访问时,每次都会执行从int到Python对象的转换,反之亦然。

Numpy

在纯Python的环境中,使用Numpy能带来更好的效果,例如:

>>> Point = numpy.dtype(('x', numpy.int32), ('y', numpy.int32), ('z', numpy.int32)])

创建初始值是0的数组

 >>> points = numpy.zeros(N, dtype=Point)
数据量 内存占用
1 000 000 12 Mb
10 000 000 120 Mb
100 000 000 1.2 Gb

最后

可以看出,在Python性能优化这方面,还是有很多事情可以做的。Python提供了方便的同时,也需要暂用较多的资源。在不通的场景下,我需要选择不同的处理方法,以便带来更好的性能体验.

更多有趣的文章,请点击我的博客

--结束END--

本文标题: 如何优化Python占用的内存

本文链接: https://www.lsjlt.com/news/192516.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

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

下载Word文档
猜你喜欢
  • 如何优化Python占用的内存
    概述 如果程序处理的数据比较多、比较复杂,那么在程序运行的时候,会占用大量的内存,当内存占用到达一定的数值,程序就有可能被操作系统终止,特别是在限制程序所使用的内存大小的场景,更容易发生问题。下面我就给出几个优化Python占用内存的几个...
    99+
    2023-01-31
    内存 Python
  • Python中怎么优化占用的内存
    今天就跟大家聊聊有关Python中怎么优化占用的内存,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Dict使用Python内置的数据结构Dict来实现上述例子的需求很简单。>&...
    99+
    2023-06-02
  • Python 中怎么优化程序占用的内存
    今天就跟大家聊聊有关Python 中怎么优化程序占用的内存,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。假设我现在有一个字典是这样的:animal = {'...
    99+
    2023-06-16
  • python如何检查内存占用
    这篇文章主要介绍了python如何检查内存占用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。检查内存占用在Python中我们可以使用内置模块...
    99+
    2024-04-02
  • python如何输出内存占用
    小编给大家分享一下python如何输出内存占用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!内存占用import sys  vari...
    99+
    2023-06-27
  • 宝塔面板内存占用率优化
    宝塔程序可以帮助我们快速搭建网站,但是笔者有一台服务器,内存只有1GB,装上宝塔后内存所剩无几,只能勉强部署一个小型服务,于是想到“精简”宝塔程序,先说结果: 初始剩余内存:218MB 优化后剩余内存:581MB 下面是具体步骤: 卸载不...
    99+
    2023-08-18
    linux 后端 服务器
  • 如何在PHP开发中优化代码性能和内存占用?
    如何在PHP开发中优化代码性能和内存占用?在进行PHP开发时,提升代码性能和优化内存占用是非常重要的。一个高效的应用程序不仅可以提升用户体验,还可以降低服务器负载和资源消耗。本文将介绍几种优化代码性能和内存占用的方法。使用合适的数据结构和算...
    99+
    2023-11-03
    算法 内存分配 并行
  • Python如何查看程序内存占用情况
    目录查看程序内存占用情况python查看内存使用查看程序内存占用情况 flyfishpsutil 这里用在查看内存占用情况memory_profiler输出每一行代码增减的内存 安装...
    99+
    2024-04-02
  • python怎么写占用内存
    在Python中,可以使用`sys.getsizeof()`函数来获取对象占用的内存大小。具体的代码示例如下:```pythonim...
    99+
    2023-08-31
    python
  • python清除函数占用的内存
    python升级到2.7.13 函数执行的结尾加上这个即可 for x in locals().keys():      del locals()[x] gc.collect() 原理是,locals()会列出当前所有...
    99+
    2023-01-31
    函数 内存 python
  • 优化golang中Select Channels Go并发式编程的内存占用
    要优化Golang中Select Channels的内存占用,可以考虑以下几点:1. 减少不必要的channel使用:在使用Sele...
    99+
    2023-10-08
    Golang
  • windows trustedinstaller.exe占用内存如何解决
    今天小编给大家分享一下windows trustedinstaller.exe占用内存如何解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一...
    99+
    2023-07-01
  • 阿里云ECS虚拟内存如何优化内存使用
    阿里云ECS虚拟内存是云计算中的一种重要资源,它决定了一个虚拟机可以运行的程序数量和程序的运行速度。然而,如何有效地使用和优化ECS虚拟内存,是每个云用户都需要了解和掌握的技能。本文将详细介绍ECS虚拟内存的使用方法和优化策略。 一、什么是...
    99+
    2023-11-07
    阿里 虚拟内存 内存
  • win11内存占用高如何解决
    本文小编为大家详细介绍“win11内存占用高如何解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“win11内存占用高如何解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。win11内存占用高怎么解决:方法一:...
    99+
    2023-06-30
  • java内存占用高如何清理
    在Java中,内存占用高可能是因为程序中存在内存泄漏或者使用了大量的不必要的对象。以下是一些清理内存的方法: 使用垃圾回收器:J...
    99+
    2024-03-02
    java
  • 如何进行linux内存的Hugepages优化
    本篇文章给大家分享的是有关如何进行linux内存的Hugepages优化,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Hugepages是从Linux kernal 2.6后被...
    99+
    2023-06-06
  • 优化Go语言应用的内存占用和垃圾回收效率
    要优化Go语言应用的内存占用和垃圾回收效率,可以采取以下几个方面的优化策略:1. 减少内存分配:避免频繁的内存分配,可以使用内存池和...
    99+
    2023-10-12
    Go语言
  • 如何查看redis数据占用的内存
    这篇文章主要介绍如何查看redis数据占用的内存,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体查看步骤如下:redis-cli auth 密码info# Memoryused_m...
    99+
    2024-04-02
  • 如何让小内存VPS使用更优化
    本篇内容主要讲解“如何让小内存VPS使用更优化”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何让小内存VPS使用更优化”吧!初尝自从今年年初开始尝试使用 VPS 后,就喜欢上了这个折腾。在 V...
    99+
    2023-06-10
  • win11如何查看内存占用情况
    这篇文章主要介绍了win11如何查看内存占用情况的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇win11如何查看内存占用情况文章都会有所收获,下面我们一起来看看吧。方法一:首先右键“windows徽标”,打开“...
    99+
    2023-07-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作