是否有一个很好的方法,在Python中,衡量内存访问的数量,或mems,由一个函数使用?



当人们询问内存时,他们通常会问使用了多少内存,但这不是我的意思。

相反,我正在通读Donald Knuth的《计算机编程的艺术》,并用Python重新创建一些算法。Knuth测量了他的一个程序在mems中运行的时间,这意味着读取或写入内存区域的次数。这是一个很好的方法来衡量一个算法所需的时间作为一个精确的数字,更独立于芯片架构或速度。

作为我正在寻找的一个例子,考虑这个示例脚本:

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

你可以说这里有5个mems,像这样:

mylist = [1, 2, 3]  # Write to `mylist`. 1 mem
x = 2               # Write to `x`.      1 mem
y = mylist[x]       # Read from `x`, `mylist`; write to `y`. 3 mems

你也可以认为对mylist的赋值应该算作多次写,因为它比单个值代表更多的内存使用。

现在,我只是试图解决一个高层次的问题,用一些(任何)方法来合理地衡量mems,理想情况下,不需要做任何花哨的魔术般的编码:)之后,我可能会开始担心更多的细节,比如"什么是最好的方法",";或者"这一行应该算多少个mems ?"但这个问题关注的是"第一种方法是什么?">

我指的是程序上的,比如,我运行一个函数,在Python的某个地方有一个变量,它记录了函数运行时使用的mems的数量。(这与人类静态地分析程序以获得计数,或手动为每次内存访问添加n += 1相反。)

我真的不知道有什么好的方法来做到这一点,但我认为这实际上违背了Knuth最初的建议。在The Stanford GraphBase中,他声明

#define o mems++
#define oo mems += 2
#define ooo mems += 3

,然后继续手动添加这些宏,例如

...
o, a->from = v;
oo, a->klink = aucket[l];
...

他这样做的理由是

(1)可以使用文本编辑器轻松快速地插入宏。(2)实现不需要为mems买单,这些mems可以通过适当的优化编译器或使C程序文本稍微复杂一些来避免;因此,作者可以使用他们良好的判断来保持程序比过度手工优化的代码更具可读性。(3)程序员应该能够准确地看到mems被充电的位置,这有助于消除瓶颈。o和oo的出现使这一点变得清晰,而不会弄乱程序文本。(4)对于仅提供诊断输出的mems,或者仅为重复检查"证明"的有效性而进行冗余计算的mems,不需要收取实现费用;作为程序的断言正在被测试。


关于"指标没有意义"的观点;因为Python不像C或汇编语言,所以请注意,Knuth提出这个方法是为了根据内存引用来比较算法。因此,即使Python处理指针,这仍然可以在竞争实现之间进行有益的比较。

最新更新