c语言中int占四个字节对吗,c语言中int都是4个字节吗

首页 > 教育培训 > 作者:YD1662023-06-18 16:41:15

如图所示,单独计算 a 和 b 列表的结果是 36 和 48,然后把它们作为 c 列表的子元素时,该列表的计算结果却仅仅才 36。(PS:我用的是 32 位解释器)

如果不使用引用方式,而是直接把子列表写进去,例如 “d = [[1,2],[1,2,3,4,5]]”,这样计算 d 列表的结果也还是 36,因为子列表是独立的对象,在 d 列表中存储的是它们的 id。

也就是说:getsizeof 方法在计算列表大小时,其结果跟元素个数相关,但跟元素本身的大小无关。

下面再看看字典的例子:

c语言中int占四个字节对吗,c语言中int都是4个字节吗(5)

明显可以看出,三个字典实际占用的全部内存不可能相等,但是 getsizeof 方法给出的结果却相同,这意味着它只关心键的数量,而不关心实际的键值对是什么内容,情况跟列表相似。

c语言中int占四个字节对吗,c语言中int都是4个字节吗(6)

“浅计算”与其它问题

有个概念叫“浅拷贝”,指的是 copy 方法只拷贝引用对象的内存地址,而非实际的引用对象。类比于这个概念,我们可以认为 getsizeof 是一种“浅计算”。

“浅计算”不关心真实的对象,所以其计算结果只是一个假象。这是一个值得注意的问题,但是注意到这点还不够,我们还可以发散地思考如下的问题:

关于第一个问题,getsizeof(x) 方法实际会调用 x 对象的__sizeof__魔术方法,对于内置对象来说,这个方法是通过 CPython 解释器实现的。

我查到这篇文章《Python中对象的内存使用(一)》,它分析了 CPython 源码,最终定位到的核心代码是这一段:

/*longobject.c*/

static Py_ssize_t
int___sizeof___impl(PyObject *self)
{
Py_ssize_t res;

res = offsetof(PyLongObject, ob_digit) Py_ABS(Py_SIZE(self))*sizeof(digit);
return res;
}

我看不懂这段代码,但是可以知道的是,它在计算 Python 对象的大小时,只跟该对象的结构体的属性相关,而没有进一步作“深度计算”。

对于 CPython 的这种实现,我们可以注意到两个层面上的区别:

由此,我有一个不成熟的猜测:基于“一切皆是对象”的设计原则,int 及其它基础的 C 数据类型在 Python 中被套上了一层“壳”,所以需要一个方法来计算它们的大小,也即是 getsizeof。

官方文档中说“All built-in objects will return correct results” [1],指的应该是数字、字符串和布尔值之类的简单对象。但是不包括列表、元组和字典等在内部存在引用关系的类型。

为什么不推广到所有内置类型上呢?我未查到这方面的解释,若有知情的同学,烦请告知。

c语言中int占四个字节对吗,c语言中int都是4个字节吗(7)

“深计算”与其它问题

与“浅计算”相对应,我们可以定义出一种“深计算”。对于前面的两个例子,“深计算”应该遍历每个内部元素以及可能的子元素,累加计算它们的字节,最后算出总的内存大小。

那么,我们应该注意的问题有:

Stackoverflow 网站上有个年代久远的问题“How do I determine the size of an object in Python?” [2],实际上问的就是如何实现“深计算”的问题。

有不同的开发者贡献了两个项目:pymplerpysize:第一个项目已发布在 Pypi 上,可以“pip install pympler”安装;第二个项目烂尾了,作者也没发布到 Pypi 上(注:Pypi 上已有个 pysize 库,是用来做格式转化的,不要混淆),但是可以在 Github 上获取到其源码。

对于前面的两个例子,我们可以拿这两个项目分别测试一下:

c语言中int占四个字节对吗,c语言中int都是4个字节吗(8)

上一页123下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.