【发布时间】:2011-08-06 16:33:21
【问题描述】:
我正在尝试使用以下代码填充预分配的字节数组:
# preallocate a block array
dt = numpy.dtype('u8')
in_memory_blocks = numpy.zeros(_AVAIL_IN_MEMORY_BLOCKS, dt)
...
# write all the blocks out, flushing only as desired
blocks_per_flush_xrange = xrange(0, blocks_per_flush)
for _ in xrange(0, num_flushes):
for block_index in blocks_per_flush_xrange:
in_memory_blocks[block_index] = random.randint(0, _BLOCK_MAX)
print('flushing bytes stored in memory...')
# commented out for SO; exists in actual code
# removing this doesn't make an order-of-magnitude difference in time
# m.update(in_memory_blocks[:blocks_per_flush])
in_memory_blocks[:blocks_per_flush].tofile(f)
几点:
-
num_flushes很低,大约在 4 - 10 -
blocks_per_flush是一个很大的数字,大约数百万 -
in_memory_blocks可以是一个相当大的缓冲区(我将其设置为低至 1MB 和高至 100MB),但时间非常一致...... -
_BLOCK_MAX是 8 字节无符号整数的最大值 -
m是hashilib.md5()
使用上述代码生成 1MB 大约需要 1 秒; 500MB 大约需要 376 秒。相比之下,我使用 rand() 的简单 C 程序可以在 8 秒内创建一个 500MB 的文件。
如何提高上述循环的性能?我很确定我忽略了导致运行时巨大差异的明显因素。
【问题讨论】:
-
与编译的特定类型迭代器(numpy内部)相比,像这样迭代任意类型(python)非常慢。如果您想要一个随机整数数组,就像您在示例中所做的那样,请使用
numpy.random.randint函数。但我怀疑这只是为了说明目的。您需要发布实际填充数组的内容以获得更具体的帮助。 -
不,我真的是在创建随机数据并计算校验和。我认为内存分配是瓶颈,而不是迭代。我可以想象内部 numpy 迭代器会更快(假设底层 C 实现将使用指针算法)。
-
请澄清:
_BLOCK_MAX是否等于255或9223372036854775807以及dt是否等于numpy.uint8或numpy.uint64? -
澄清一下:我的代码将
dt作为numpy.uint64和_BLOCK_MAX作为uint64的上限。
标签: python optimization numpy