为什么这个 Python NumPy 代码,
import numpy as np
import time
k_max = 40000
N = 10000
data = np.zeros((2,N))
coefs = np.zeros((k_max,2),dtype=float)
t1 = time.time()
for k in xrange(1,k_max+1):
cos_k = np.cos(k*data[0,:])
sin_k = np.sin(k*data[0,:])
coefs[k-1,0] = (data[1,-1]-data[1,0]) + np.sum(data[1,:-1]*(cos_k[:-1] - cos_k[1:]))
coefs[k-1,1] = np.sum(data[1,:-1]*(sin_k[:-1] - sin_k[1:]))
t2 = time.time()
print('Time:')
print(t2-t1)
比下面的 C++ 代码更快?
#include <cstdio>
#include <iostream>
#include <cmath>
#include <time.h>
using namespace std;
// consts
const unsigned int k_max = 40000;
const unsigned int N = 10000;
int main()
{
time_t start, stop;
double diff;
// table with data
double data1[ N ];
double data2[ N ];
// table of results
double coefs1[ k_max ];
double coefs2[ k_max ];
// main loop
time( & start );
for( unsigned int j = 1; j<N; j++ )
{
for( unsigned int i = 0; i<k_max; i++ )
{
coefs1[ i ] += data2[ j-1 ]*(cos((i+1)*data1[ j-1 ]) - cos((i+1)*data1[ j ]));
coefs2[ i ] += data2[ j-1 ]*(sin((i+1)*data1[ j-1 ]) - sin((i+1)*data1[ j ]));
}
}
// end of main loop
time( & stop );
// speed result
diff = difftime( stop, start );
cout << "Time: " << diff << " seconds";
return 0;
}
第一个显示:“时间:8 秒”,而第二个:“时间:11 秒”
我知道 NumPy 是用 C 编写的,但我仍然认为 C++ 示例会更快。我错过了什么吗?有没有办法改进 C++ 代码(或 Python 代码)?
代码版本 2
我已按照其中一条评论的建议更改了 C++ 代码(将动态表更改为静态表)。 C++ 代码现在更快,但仍然比 Python 版本慢得多。
代码版本 3
我已从调试模式更改为发布模式,并将“k”从 4000 增加到 40000。现在 NumPy 稍微快一点(8 秒到 11 秒)。
原文由 Mateusz 发布,翻译遵循 CC BY-SA 4.0 许可协议
我发现这个问题很有趣,因为每次我遇到关于 NumPy 速度(与 C/C++ 相比)的类似话题时,总是会有类似“它是一个瘦包装器,它的核心是用 C 编写的,所以它很快”这样的答案,但是这个没有解释为什么 C 应该比带有附加层的 C 慢(即使是薄层)。
答案是: 正确编译后,您的 C++ 代码不会比 Python 代码慢。
我做了一些基准测试,起初 NumPy 似乎快得惊人。但我忘了用 GCC 优化编译。
我再次计算了所有内容,并将结果与您的代码的纯 C 版本进行了比较。我正在使用 GCC 版本 4.9.2 和 Python 2.7.9(使用相同的 GCC 从源代码编译)。要编译我使用的 C++ 代码
g++ -O3 main.cpp -o main
,要编译我使用的 C 代码gcc -O3 main.c -lm -o main
。在所有示例中,我用一些数字(0.1、0.4)填充了data
变量,因为它会改变结果。我还将 np.arrays 更改为使用双精度数(dtype=np.float64
),因为 C++ 示例中有双精度数。我的代码的纯 C 版本(类似):对于
k_max = 100000, N = 10000
结果如下:Python 和 C++ 的时间基本相同,但请注意,有一个长度为 k_max 的 Python 循环,与 C/C++ 相比,它应该慢得多。它是。
对于
k_max = 1000000, N = 1000
我们有:对于
k_max = 1000000, N = 100
:So the difference increases with fraction
k_max/N
, but python is not faster even forN
much bigger thank_max
, egk_max = 100, N = 100000
:显然,C/C++ 和 Python 的主要速度差异在于
for
循环。但我想找出在 NumPy 和 C 中对数组进行简单操作之间的区别。在代码中使用 NumPy 的优点包括:1. 将整个数组乘以一个数字,2. 计算整个数组的 sin/cos, 3. 对数组的所有元素求和,而不是分别对每个项目进行这些操作。所以我准备了两个脚本来只比较这些操作。Python脚本:
C脚本:
蟒蛇结果:
C 结果:
如您所见,NumPy 非常快,但总是比纯 C 慢一点。