为什么我的Python NumPy代码比C ++快?

为什么我的Python NumPy代码比C ++快?,第1张

为什么我的Python NumPy代码比C ++快?

我发现这个问题很有趣,因为每次遇到类似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慢一些。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5631916.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存