使用__slots__节省python内存技巧
__slots__作用
__slots__有一个作用是:限制类实例绑定的属性,但是它有一个更重要的作用就是节省内存,当然更适用于数据量大的情况(万量级以上)。
__slots__节省内存的原理
class Measurement:
def __init__(self, x, y, value):
self.x = x
self.y = y
self.val = value
m1 = Measurement(1, 2, "Happy")
m2 = Measurement(7, 10, "Crazy")
m2.other = True
其实,对类的变量值进行初始化,底层是通过一个指针指向__dict__(里面包含潜在的字段名和字段值)。举个例子,上面的程序底层实现过程如下:
我们也可以通过程序查看这一底层形式:
```
print(m1.__dict__) # {'x': 1, 'y': 2, 'val': 'Happy'}
print(m2.__dict__) # {'x': 7, 'y': 10, 'other': True, 'val': 'Crazy'}
```
这就是python自定义变量底层的一个基本实现。通过对这一底层理解,我们就会知道,如果我们的实例有数百万个,那么底层会有相应数百万个字典拥有相同的key值(知识value值不同),这时非常耗内存的,这时候__slots__就发挥它的作用了。
通过__slots__,我们可以稍微调整一下类,以改变类中字段的存储方式,废弃原来那种耗费内存的1对1重复的字典分配方式。具体如下:
class Measurement:
__slots__ = ['x', 'y', 'val']
def __init__(self, x, y, value):
self.x = x
self.y = y
self.val = value
这样我们底层的实现就会变为如下方式:
我们可以看出,现在字段名是与Measurement类这个类型相关联,而不是原来的与相应的实例1对1的关联。而字段值与原来的方式无差别,因为毕竟各个实例的字段名一样,可以统一存放,而字段值并不都是一样,当然对于字段值也一样的我们也统一存储(因为底层字典都是与类这个类型关联,而不是与每个实例的__dict__关联)。但对于数据量庞大的情况(数百万级以上),能够非常显著的节省内存空间(25.5GB -> 16.2GB)。
以上就是__slots__能够节省内存的原理,主要还是要搞清楚python的类变量初始化的底层操作是通过字典存储后相关联这一方式进行的,__slots__只是改变了字典key,value与实例相关联的方式,可以总结如下:
默认变量实例化方法:底层实例和字典是一对一的关系
加入__slots__后:底层实例和字典是多对一的关系(重复的部分)。
使用__slots__节省python内存技巧的更多相关文章
- 填坑总结:python内存泄漏排查小技巧
摘要:最近服务遇到了内存泄漏问题,运维同学紧急呼叫解决,于是在解决问题之余也系统记录了下内存泄漏问题的常见解决思路. 本文分享自华为云社区<python内存泄漏排查小技巧>,作者:luti ...
- Python内存优化
实际项目中,pythoner更加关注的是Python的性能问题,之前也写过一篇文章<Python性能优化>介绍Python性能优化的一些方法.而本文,关注的是Python的内存优化,一般说 ...
- Python内存优化:Profile,slots,compact dict
实际项目中,pythoner更加关注的是Python的性能问题,之前也写过一篇文章<Python性能优化>介绍Python性能优化的一些方法.而本文,关注的是Python的内存优化,一般说 ...
- Python内存管理机制及优化简析(转载)
from:http://kkpattern.github.io/2015/06/20/python-memory-optimization-zh.html 准备工作 为了方便解释Python的内存管理 ...
- 记一次调试python内存泄露的问题
转载:http://www.jianshu.com/p/2d06a1a01cc3 这两天由于公司需要, 自己编写了一个用于接收dicom文件(医学图像文件)的server. 经过各种coding-de ...
- Python内存分配器(如何产生一个对象的过程)
目录 内存分配器 Python分配器分层 第零层--通用的基础分配器 第一层--低级内存分配器 内存结构 arena pool new arena usable_arenas和unused_arena ...
- 【python测试开发栈】—python内存管理机制(二)—垃圾回收
在上一篇文章中(python 内存管理机制-引用计数)中,我们介绍了python内存管理机制中的引用计数,python正是通过它来有效的管理内存.今天来介绍python的垃圾回收,其主要策略是引用计数 ...
- python实用技巧之任务切分
Python 大任务切分小任务 今天来说说,Python中的任务切分.以爬虫为例,从一个存 url 的 txt 文件中,读取其内容,我们会获取一个 url 列表.我们把这一个 url 列表称为大任务. ...
- python内存管理(通俗易懂,详细可靠)
python内存管理 python3.6.9 内存管理的官方文档 https://docs.python.org/zh-cn/3.6/c-api/memory.html 一.变量存哪了? x = 10 ...
随机推荐
- ubuntu下安装mysql和配置远程访问
ubuntu下安装mysql和配置远程访问 下载安装mysql sudo apt-get install mysql-client mysql-server 安装的时候会提示要设置root密码,如 ...
- BAT批处理文件,脚本时间值%time:~0,2%%time:~3,2%%time:~6,2%的用法。
最近公司的项目,需要部署一个oracle定时备份脚本,删除掉特定时间前的备份文件.BAT批处理文件结合windows系统(任务计划程序) 正常情况下我们的任务计划会有反馈数值,通过它可以判断这个任务计 ...
- 第3章 Java数组(上): 一维数组和二维数组
3.数组及排序算法(2天) 3.1 数组的概述 2课时 3.2 一维数组的使用 3课时 3.3 多维数组的使用 3课时 3.4 数组中涉及到的常见算法 3课时 3.5 Arrays工具类的使用 3课时 ...
- Centos7更改yum源
每次都要百度一番,还不如自己做个记录,简单粗暴,哈哈哈哈 cd /etc/yum.repos.d mv CentOS-Base.repo CentOS-Base.repo.old wget http: ...
- MySQL 和 Oracle 在 MyBatis 使用中的区别
MySQL 和 Oracle 在 MyBatis 使用中的区别: 区别 MySQL Oracle 存储过程的参数模式 mode 为 IN 时,是否需要指定 jdbcType 不需要:MyBatis 为 ...
- 打印 laravel 模型查询产品的 SQL
1.在路由閉包打印sql 打印一段代码生产的 sql 语句,使用路由闭包做个实验 Route::get('/get-sql', function() { DB::enableQueryLog(); $ ...
- Tomcat整体架构分析
下面让我们来看看Tomcat容器的整体结构: 本文的目的是覆盖这张图中所涉及的主要请求处理组件.而上图中的一些高级主题如集群和安全则不是在本文讨论的范围之内. 本图中,Service, Host, C ...
- 数论卷积公式and莫比乌斯反演
数论卷积: 对于两个数论函数f(x),g(x) f(n)g(n)=∑ f(d)g(n/d) d|n 莫比乌斯函数: 设一个数n=(p1^k1)*(p2^k2)*(p3^k3)*..........*( ...
- pytorch下的lib库 源码阅读笔记(1)
置顶:将pytorch clone到本地,查看initial commit,已经是麻雀虽小五脏俱全了,非常适合作为学习模板. 2017年12月7日01:24:15 2017-10-25 17:51 参 ...
- eclipse中配置MAVEN并使用阿里云代理
一.下载MAVENhttp://maven.apache.org/download.cgi 二.配置MAVEN环境变量名:M2_HOME变量值:F:\maven\apache-maven-3.0.3找 ...