我发现这个问题很有趣,因为每次遇到类似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 -O3main.c -lm -o main
。在所有示例中,我都会data
用一些数字(0.1、0.4)填充变量,因为它会改变结果。我也将
np.arrays 更改为使用doubles(dtype=np.float64
),因为C 示例中存在double。我的代码的纯C版本(类似):
#include <math.h>#include <stdio.h>#include <time.h>const int k_max = 100000;const int N = 10000;int main(void){ clock_t t_start, t_end; double data1[N], data2[N], coefs1[k_max], coefs2[k_max], seconds; int z; for( z = 0; z < N; z++ ) { data1[z] = 0.1; data2[z] = 0.4; } int i, j; t_start = clock(); for( i = 0; i < k_max; i++ ) { for( j = 0; j < N-1; j++ ) { coefs1[i] += data2[j] * (cos((i+1) * data1[j]) - cos((i+1) * data1[j+1])); coefs2[i] += data2[j] * (sin((i+1) * data1[j]) - sin((i+1) * data1[j+1])); } } t_end = clock(); seconds = (double)(t_end - t_start) / CLOCKS_PER_SEC; printf("Time: %f sn", seconds); return coefs1[0];}
对于
k_max = 100000, N = 10000以下结果:
- Python 70.284362秒
- C ++ 69.133199秒
- C 61.638186 s
Python和C 基本上具有相同的时间,但请注意,存在一个长度为k_max的Python循环,与C / C 相比,它应该慢得多。是的。
因为
k_max = 1000000, N = 1000我们有:
- Python 115.42766秒
- C ++ 70.781380秒
对于
k_max = 1000000, N = 100:
- Python 52.86826秒
- C ++ 7.050597秒
因此,差异随分数增加
k_max/N,但是python甚至
N比python快得多
k_max,例如,速度也不快
k_max = 100, N =100000:
- Python 0.651587秒
- C ++ 0.568518秒
显然,C / C
++和Python之间的主要速度差异在于
for循环。但是我想找出在NumPy和C中对数组进行简单 *** 作之间的区别。在代码中使用NumPy的优点包括:1.将整个数组乘以一个数字,2.计算整个数组的sin
/ cos, 3.对数组的所有元素求和,而不是分别对每个单个项目执行这些 *** 作。因此,我准备了两个脚本来仅比较这些 *** 作。
Python脚本:
import numpy as npfrom time import timeN = 10000x_len = 100000def main(): x = np.ones(x_len, dtype=np.float64) * 1.2345 start = time() for i in xrange(N): y1 = np.cos(x, dtype=np.float64) end = time() print('cos: {} s'.format(end-start)) start = time() for i in xrange(N): y2 = x * 7.9463 end = time() print('multi: {} s'.format(end-start)) start = time() for i in xrange(N): res = np.sum(x, dtype=np.float64) end = time() print('sum: {} s'.format(end-start)) return y1, y2, resif __name__ == '__main__': main()# results# cos: 22.7199969292 s# multi: 0.841291189194 s# sum: 1.15971088409 s
C脚本:
#include <math.h>#include <stdio.h>#include <time.h>const int N = 10000;const int x_len = 100000;int main(){ clock_t t_start, t_end; double x[x_len], y1[x_len], y2[x_len], res, time; int i, j; for( i = 0; i < x_len; i++ ) { x[i] = 1.2345; } t_start = clock(); for( j = 0; j < N; j++ ) { for( i = 0; i < x_len; i++ ) { y1[i] = cos(x[i]); } } t_end = clock(); time = (double)(t_end - t_start) / CLOCKS_PER_SEC; printf("cos: %f sn", time); t_start = clock(); for( j = 0; j < N; j++ ) { for( i = 0; i < x_len; i++ ) { y2[i] = x[i] * 7.9463; } } t_end = clock(); time = (double)(t_end - t_start) / CLOCKS_PER_SEC; printf("multi: %f sn", time); t_start = clock(); for( j = 0; j < N; j++ ) { res = 0.0; for( i = 0; i < x_len; i++ ) { res += x[i]; } } t_end = clock(); time = (double)(t_end - t_start) / CLOCKS_PER_SEC; printf("sum: %f sn", time); return y1[0], y2[0], res;}// results// cos: 20.910590 s// multi: 0.633281 s// sum: 1.153001 s
Python结果:
- cos:22.7199969292 s
- 多:0.841291189194 s
- 总和:1.15971088409 s
C结果:
- cos:20.910590 s
- 多:0.633281 s
- 总和:1.153001 s
如您所见,NumPy的速度非常快,但始终比纯C慢一些。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)