概要
如果算术表达式既包含
numpy数字又包含内置数字,则Python算术的运行速度较慢。避免这种转换消除了我报告的几乎所有性能下降。
细节
请注意,在我的原始代码中:
s = np.float64(1)for i in range(10000000): s = (s + 8) * s % 2399232
类型
float和
numpy.float64混合在一个表达式中。也许Python必须将它们全部转换为一种类型?
s = np.float64(1)for i in range(10000000): s = (s + np.float64(8)) * s % np.float64(2399232)
如果运行时保持不变(而不是增加),则表明Python确实在做这件事,从而解释了性能下降。
实际上,运行时间减少了1.5倍!这怎么可能?Python可能要做的最坏的事情不是这两次转换吗?
我真的不知道
也许Python必须动态地检查需要将哪些内容转换为哪些内容,这需要花费时间,并且被告知要执行的精确转换可以使其更快。也许,某种完全不同的机制用于算术(根本不涉及转换),并且在不匹配的类型上碰巧超慢。阅读
numpy源代码可能会有所帮助,但这超出了我的能力。
无论如何,现在我们显然可以通过将转换移出循环来加快处理速度:
q = np.float64(8)r = np.float64(2399232)for i in range(10000000): s = (s + q) * s % r
正如预期的那样,运行时间大大减少:又减少了2.3倍。
公平地说,我们现在需要
float通过将文字常量移出循环来稍微更改版本。这会导致极小的(10%)减速。
考虑到所有这些更改,
np.float64代码的版本现在仅比等效
float版本慢30%。荒谬的5倍性能影响已基本消失。
为什么我们仍然看到30%的延迟?
numpy.float64数字占用与相同的空间
float,所以这不是原因。对于用户定义的类型,算术运算符的解析可能需要更长的时间。当然不是主要问题。



