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

Python中如何编程统计函数的内存访问次数(mems)?

实现Python代码的自动mems(内存读写操作次数)统计

通常大家聊内存相关问题时,关注的都是内存占用量,但这里我们要实现的是Donald Knuth在《The Art of Computer Programming》里提出的mems统计——也就是统计程序执行过程中内存读写操作的总次数,这种度量方式不依赖具体芯片架构和速度,能更精确地衡量算法耗时。

统计规则示例

先明确统计逻辑,以下面的代码为例:

mylist = [1, 2, 3]
x = 2
y = mylist[x]

按照约定的统计规则,这段代码总共对应5次mems:

mylist = [1, 2, 3]  # 写入`mylist`,1次mem
x = 2               # 写入`x`,1次mem
y = mylist[x]       # 读取`x`、`mylist`,写入`y`,3次mems

当然也有争议,比如有人认为列表赋值应该按元素数量算多次写入,但当前我们只需要一套合理的统计逻辑,后续再优化细节。

自动统计的实现方案

要实现运行函数时自动统计mems,不需要手动加计数代码,可以利用Python的sys.settrace钩子跟踪字节码执行,识别变量的读写操作并计数。

下面是一个简单的装饰器实现:

import sys

def count_mems(func):
    mem_count = 0

    def trace_func(frame, event, arg):
        nonlocal mem_count
        if event == 'opcode':
            # 字节码对应操作:LOAD_NAME/LOAD_FAST是读取变量,STORE_NAME/STORE_FAST是写入变量
            opcode = frame.f_code.co_code[frame.f_lasti]
            # 0x19=LOAD_NAME, 0x1a=LOAD_FAST;0x52=STORE_NAME, 0x53=STORE_FAST
            if opcode in (0x19, 0x1a):
                mem_count += 1
            elif opcode in (0x52, 0x53):
                mem_count += 1
        return trace_func

    def wrapper(*args, **kwargs):
        nonlocal mem_count
        mem_count = 0
        original_trace = sys.gettrace()
        sys.settrace(trace_func)
        try:
            result = func(*args, **kwargs)
            print(f"Total mems: {mem_count}")
            return result
        finally:
            sys.settrace(original_trace)
    return wrapper

使用示例

把需要统计的函数用这个装饰器修饰即可:

@count_mems
def test():
    mylist = [1, 2, 3]
    x = 2
    y = mylist[x]

test()
# 输出:Total mems: 5

说明

这个实现基于Python的字节码跟踪,识别变量的读取(LOAD_*系列字节码)和写入(STORE_*系列字节码)操作,每一次对应1次mem。当前逻辑和示例中的统计规则一致,把列表赋值算作1次写入;如果后续需要调整统计规则(比如列表元素单独计数),只需要修改trace_func里的判断逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:25:48