我有一些很难看的索引正在进行。例如
valid[ data[ index[valid[:,0],0] ] == 0, 1] = False
其中valid
和index
分别是{Nx2}数组或bool
s和int
s,并且data
是{N}长的。你知道吗
如果我真的很努力,我可以说服自己,这是我想做的。。。但它令人难以置信的混乱。我怎样才能有效地解开这样的谜团?
我可以打破它,例如:
valid_index = index[valid[:,0],0]
invalid_index = (data[ valid_index ] == 0)
valid[ invalid_index, 1 ] = False
但是我的数组将有多达1亿个条目,所以我不想复制内存;我需要尽可能保持速度效率。你知道吗
这两个代码序列几乎相同,应该具有非常相似的性能。这是我的“直觉”,但后来我做了静态分析,运行了部分基准来确认。你知道吗
更清晰的选项需要另外四个字节码来实现,因此可能会稍微慢一点。但是额外的工作仅限于
LOAD_FAST
和STORE_FAST
,它们只是从栈顶(TOS
)到变量的移动。由于额外的工作是适度的,所以应该是性能影响。你知道吗您可以在目标设备上对这两种方法进行基准测试,以获得更高的定量精度,但在我3岁的笔记本电脑上,在标准cpython2.7.5上,额外的1亿对
LOAD_FAST
/STORE_FAST
只需3秒多。因此,我估计每100米参赛者的清晰度大约需要6秒。虽然PyPy即时Python编译器不使用相同的字节码,但我将清除版本的开销定为大约一半,即每100M 3秒。与处理项目的其他工作相比,清除版本可能不是一个重要的决战。你知道吗TL;Backstory博士
我的第一印象是,虽然代码序列在可读性和清晰度方面有所不同,但在技术上非常相似,不应具有类似的性能特征。但是让我们使用Python反汇编程序进一步分析一下。我将每个代码片段放入一个函数中:
然后使用Python's bytecode dissassember:
提供:
相似但不完全相同,顺序也不相同。一个快速的diff of the two也显示了同样的情况,而且更清晰的函数可能需要更多的字节码。你知道吗
我从每个函数的反汇编程序列表中解析字节码操作码,将它们放入
collections.Counter
,并比较计数:很明显,第二种更清晰的方法只使用了四个字节码,而且是简单、快速的
LOAD_FAST
/STORE_FAST
类型。因此,静态分析没有特别的理由担心额外的内存分配或其他破坏性能的副作用。你知道吗然后我构造了两个非常相似的函数,反汇编程序显示的不同之处只是第二个函数有一个额外的
LOAD_FAST
/STORE_FAST
对。我运行了100000000次,比较了它们的运行时间。它们在cpython2.7.5中相差3秒多,在pypy2.2.1(基于python2.7.3)中相差1.5秒左右。即使您将这些时间翻了一番(因为您有两对),很明显,这些额外的加载/存储对也不会让您慢很多。你知道吗相关问题 更多 >
编程相关推荐