对于以下代码,我的时间真的很奇怪:
import numpy as np
s = 0
for i in range(10000000):
s += np.float64(1) # replace with np.float32 and built-in float
为什么要float64
慢两倍float
?为什么float32
比float64慢5倍?
有什么方法可以避免使用的代价np.float64
,并使numpy
函数返回内置float
而不是float64
?
我发现使用numpy.float64
速度比Python的float慢得多,numpy.float32
甚至更慢(即使我使用的是32位计算机)。
numpy.float32
在我的32位计算机上。因此,每次使用诸如的各种numpy函数时numpy.random.uniform
,我都会将结果转换为float32
(以便进一步的操作以32位精度执行)。
有什么方法可以在程序或命令行中的某个位置设置单个变量,并使所有numpy函数返回float32
而不是float64
?
编辑#1:
在算术计算中,numpy.float64比float慢 10倍
。太糟糕了,以至于在计算之前,即使转换为浮点数并返回,也会使程序运行速度提高3倍。为什么?有什么我可以解决的吗?
我想强调一下,我的时间并不是由于以下任何原因:
我更新了代码,以更清楚地找出问题所在。使用新代码,似乎我发现使用numpy数据类型的性能下降了十倍:
from datetime import datetime
import numpy as np
START_TIME = datetime.now()
# one of the following lines is uncommented before execution
#s = np.float64(1)
#s = np.float32(1)
#s = 1.0
for i in range(10000000):
s = (s + 8) * s % 2399232
print(s)
print('Runtime:', datetime.now() - START_TIME)
时间是:
只是为了它的地狱,我还尝试了:
从datetime导入datetime导入numpy为np
START_TIME = datetime.now()
s = np.float64(1)
for i in range(10000000):
s = float(s)
s = (s + 8) * s % 2399232
s = np.float64(s)
print(s)
print('Runtime:', datetime.now() - START_TIME)
执行时间为13.28
s;实际上,将来回转换的速度比按原样使用float64
要快3倍float
。尽管如此,转换还是要付出代价的,因此,与纯python相比,总体而言,转换速度要慢3倍以上float
。
我的机器是:
编辑2:
感谢您的回答,它们可以帮助我了解如何处理此问题。
但是我仍然想知道确切的原因(也许基于源代码),为什么下面的代码运行速度float64
比with慢10倍float
。
编辑#3:
我在Windows 7 x64(Intel Core i7 930 @ 3.8GHz)下重新运行代码。
再次,代码是:
from datetime import datetime
import numpy as np
START_TIME = datetime.now()
# one of the following lines is uncommented before execution
#s = np.float64(1)
#s = np.float32(1)
#s = 1.0
for i in range(10000000):
s = (s + 8) * s % 2399232
print(s)
print('Runtime:', datetime.now() - START_TIME)
时间是:
现在,两个np
浮点数(64或32)都比内置浮点数慢5倍float
。尽管如此,还是有很大的区别。我试图弄清楚它的来源。
编辑结束
概要
如果算术表达式既包含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
,所以这不是原因。对于用户定义的类型,算术运算符的解析可能需要更长的时间。当然不是主要问题。
当我尝试测量算术运算的执行时间时,我遇到了非常奇怪的行为。包含< code>for循环且循环体中有一个算术运算的代码块的执行速度总是慢于在< code>for循环体中有两个算术运算的相同代码块。下面是我最后测试的代码: 我测试了不同级别的代码优化(,,和),使用不同的在线编译器(例如onlinegdb.com),在我的工作机器上,在我的hame PC和笔记本电脑上,在RaspberryPi和同事的
我有一个简单的程序来测量浮点乘法(和随机生成,编译g-O0)。在主机(Ubuntu 16.04)上运行时,每10000000次乘法得到约1.6秒,在图像“Ubuntu”的容器中运行时(无需重新编译),得到约3.6秒。有人能解释为什么它慢了2.5倍吗? p、 我多次运行程序来消除异常值。我不需要优化它,只需要详细解释那里发生了什么。 编译 要在构建后使用的容器内运行:
问题内容: 使用算术运算符比较是否为内置类型(在这种情况下为整数)进行了定义? 语言规范的前两个比较部分和第三个比较部分之间的区别(Python的规范-您一定是在开玩笑))还是CPython的实现细节? 问题答案: 您真正可以使用的唯一有意义的比较是(或)。 出于各种原因,已从Python 3中删除了不同类型之间的比较-它们是常见的错误来源,并导致混乱。例如 在Python 3中,比较不同类型的值
主要内容:numpy.reciprocal(),numpy.power(),numpy.mod(),复数数组处理函数NumPy 数组的“加减乘除”算术运算,分别对应 add()、subtract()、multiple() 以及 divide() 函数。 注意:做算术运算时,输入数组必须具有相同的形状,或者符合数组的广播规则,才可以执行运算。 下面看一组示例: 输出结果: 下面介绍了 NumPy 中其他重要的算术运算函数。 numpy.reciprocal() 该函数对数组中的每个元素取倒数,并
大多数都要进行算术运算。算术运算符见图 1.10,注意这里使用了许多代数中没有使用的符号。星号(*)表示乘法、百分号(%)表示求模(modulus)将在稍后介绍。图1.10所示的算术运算符都是二元运算符,即这些运算符取两个操作数。例如表达式 "integer1+integer2" 包含二元运算符 “+” 和两个操作数 integer1 和 integer2。 C++操作 算术运算符 代数表达式 C
运算符是处理数据的基本方法,用来从现有的值得到新的值。JavaScript 提供了多种运算符,覆盖了所有主要的运算。 概述 JavaScript 共提供10个算术运算符,用来完成基本的算术运算。 加法运算符:x + y 减法运算符: x - y 乘法运算符: x * y 除法运算符:x / y 指数运算符:x ** y 余数运算符:x % y 自增运算符:++x 或者 x++ 自减运算符:--x