C循环快还是Matlab矩阵快,R、MATLA、Python和C多重循环效率对比

  • Post author:
  • Post category:python


昨天为了求加权后的集聚系数用R写了段代码,效率实在是不敢恭维,于是我进行了一些测试,希望能有所启发。MATLAB写这篇评论时才想到添加进来做对比的,添加的理由很简单,MATLAB与R都是重要的数据挖掘工具。然后对比了通用脚本语言Python,这个对比理由很简单,他们都是脚本类语言。最后就是与通用语言C的比较,是为了引入比较的基准。

问题

(来自复杂网络)对表示为有权邻接矩阵A的图求其加权集聚系数。

形式化描述

36896508_1

其中,cw(i)为结点i的加权集聚系数,si是结点强度即

36896508_2
,ki是结点度,aij是A第i行j列的元素。

数据详情

结点数量为576,边数达到完全图的75%。5763=191102976,2亿运算级,复杂程度并不高(现在的CPU主频都在2G以上)。

注:在这里用矩阵做是因为R里面用矩阵运算很方便,并且这里问题规模并不大。

实验

分别用四种语言(代码见附录)对上面的问题进行了求解,公平起见只计算了三重循环部分的耗时。实验结果差别很大很大,C语言只用了“瞬间”就完成了,Python大概是其它两种脚本速度的10倍。本以为Matlab会很快,想不到与R一样,都需要让人无法等待的时间,下面列举的Matlab和R的时间表示计算一个结点的加权集聚系数所需要的时间,虽然每一次需要的时间是浮动的,但是都是在4附近。

运行时间一览

语言

语言

C

Python

Matlab

R

耗时(秒)

2

246

>4*576

>4*576

小结

通过实际计时表明,Matlab和R这样的专一脚本,不适合做复杂度高的脚本编程(比如矩阵相乘用Matlab和R写,效率显然要比调用它们的内置模块慢好几个数量级)通用语言。这样看来,对于复杂的模块,写调用的C接口还是很有必要的。

测试数据及代码(skydrive,点击)

2012.5.11日更新

刘凯写了一份java的代码放到了测试中,结果令人很惊讶,java的平均表现为1.7。然后我对C的计时器进行了细化,采用了亳秒级别的,C大致在2.3左右。这个确实能说明一些问题,优化!不同的优化使得代码在有些方面会比较擅长!同理,Python,Matlab中的特定优化过的模块不一定会比Java差。在这里,java是没有理由比C更快的,不就是有针对性的优化吗?C(gcc)也是可以的,在开启了-O3优化选项后,C的执行时间降到了1.4左右(在这里没有做严格的统计,比如运行多少次,方差什么的,目测影响很小,有兴趣可以做严格实验)。再列一份最终统计表:

36896508_3