You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python @dataclasses 中 pympler.asizeof 测量结果受参数顺序影响的原因?

核心原因

pympler的asizesof函数默认会去重统计已经计算过的对象,避免共享对象被重复计算大小,入参顺序决定了共享对象被第一次统计的时机,进而影响每个入参最终的数值。

具体逻辑说明

  • asizesof会按入参顺序逐个处理对象,统计对象总大小时会递归遍历它引用的所有子对象,所有已经被统计过的对象(包括前面入参的对象本身、它们引用的子对象)不会再被计入后续对象的大小中。
  • 你的测试场景里存在大量共享对象:整数1、2是Python驻留的全局唯一小整数,test_1和test_2的属性都引用了这两个相同的对象。
  • 两个测试类的内存结构不同:
    • 带__slots__的TEST1实例没有独立的__dict__属性,自身基础内存更小
    • 不带__slots__的TEST2实例自带存储属性的__dict__字典,自身基础内存更大,__dict__本身也需要计入总大小

补充:这个去重逻辑是有意设计的,如果你把asizesof返回的所有值加总,总和就是这组对象的总内存占用(共享部分只算一次),总大小不会受入参顺序影响,受影响的只是每个单独入参的统计值。

对应测试结果解释

举两组结果对比即可验证逻辑:

  1. 调用asizesof(test_1, test_2)返回(112, 264)
    • 先处理test_1:第一次统计到整数1、2,这两个的大小会被计入test_1的总大小,最终得到112
    • 后处理test_2:整数1、2已经被统计过不再重复计算,只统计test_2自身和它的__dict__大小,得到264
  2. 调用asizesof(test_2, test_1)返回(328, 48)
    • 先处理test_2:第一次统计到整数1、2、test_2本身和它的__dict__,全部加起来得到328
    • 后处理test_1:整数1、2已经被统计过,只需要算test_1自身的基础大小,得到48

解决方案

如果你需要统计每个对象的独立全量大小,避免入参之间互相影响,不要把多个对象放在同一个asizesof调用里,逐个单独调用asizeof.asizeof()即可,比如:

print(asizeof.asizeof(test_1), asizeof.asizeof(test_2))

这样每次统计都会从零开始计数,不会出现顺序影响结果的问题。

内容的提问来源于stack exchange,提问作者tomm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 03:24:04