Python 我不知道';我不明白这些方法中的一种为什么/如何比其他方法快
我想测试一些简单代码的实现之间的时间差异。我决定统计10000000个随机样本中有多少个值大于0.5。从[0.0,1.0]范围内均匀采集随机样本 这是我的密码:Python 我不知道';我不明白这些方法中的一种为什么/如何比其他方法快,python,optimization,numpy,Python,Optimization,Numpy,我想测试一些简单代码的实现之间的时间差异。我决定统计10000000个随机样本中有多少个值大于0.5。从[0.0,1.0]范围内均匀采集随机样本 这是我的密码: from numpy.random import random_sample; import time; n = 10000000; t1 = time.clock(); t = 0; z = random_sample(n); for x in z: if x > 0.5: t += 1; print t; t2
from numpy.random import random_sample; import time;
n = 10000000;
t1 = time.clock();
t = 0;
z = random_sample(n);
for x in z:
if x > 0.5: t += 1;
print t;
t2 = time.clock();
t = 0;
for _ in xrange(n):
if random_sample() > 0.5: t += 1;
print t;
t3 = time.clock();
t = (random_sample(n) > 0.5).sum();
print t;
t4 = time.clock();
print t2-t1; print t3-t2; print t4-t3;
这是输出:
4999445
4999511
5001498
7.0348236652
1.75569394301
0.202538106332
我知道第一个实现很糟糕,因为创建一个庞大的数组,然后按元素计算是个坏主意,所以我认为第二个实现将是最有效的 但是第三种方法的实现速度是第二种方法的10倍吗?第三种方法不也是以
random\u sample(n)
的形式创建一个庞大的数组,然后根据0.5检查值吗
第三种方法与第一种方法有何不同?为什么比第一种方法快35倍
编辑:@merlin2011建议方法3可能不会在内存中创建完整的数组。因此,为了测试该理论,我尝试了以下方法:
z = random_sample(n);
t = (z > 0.5).sum();
print t;
在0.197948451549
的时间内运行,这实际上与方法3相同。因此,这可能不是一个因素
sum()
在C
中被实现为一个循环,但我不是100%确定。我猜这会更快,原因与Matlab矢量化比Matlab中的循环快一样
z = random_sample(n)
z2 = z > 0.5
t = z2.sum();
在前两种方法中,您都调用Python的标准功能来执行循环,这比烘焙到实现中的C级循环慢得多
sum()
在C
中被实现为一个循环,但我不是100%确定。我猜这会更快,原因与Matlab矢量化比Matlab中的循环快一样
z = random_sample(n)
z2 = z > 0.5
t = z2.sum();
在前两种方法中,您都调用Python的标准功能来执行循环,这比烘焙到实现中的C级循环慢得多
sum()
在C
中被实现为一个循环,但我不是100%确定。我猜这会更快,原因与Matlab矢量化比Matlab中的循环快一样
z = random_sample(n)
z2 = z > 0.5
t = z2.sum();
在前两种方法中,您都调用Python的标准功能来执行循环,这比烘焙到实现中的C级循环慢得多
sum()
在C
中被实现为一个循环,但我不是100%确定。我猜这会更快,原因与Matlab矢量化比Matlab中的循环快一样
z = random_sample(n)
z2 = z > 0.5
t = z2.sum();
在前两种方法中,您都调用Python的标准功能来执行循环,这比烘焙到实现中的C级循环慢得多。AFAIK
- 函数调用很重,在方法2上,调用
10000000次,但在第三个方法上,只调用一次random\u sample()
- Numpy的
和
在C语言中优化到最后一位,也很可能使用SIMD指令来避免循环.sum
- 函数调用很重,在方法2上,调用
10000000次,但在第三个方法上,只调用一次random\u sample()
- Numpy的
和
在C语言中被优化到最后一位,也是最重要的.sum