最近学习面板数据的蒙特卡洛模拟编程。编程过程中,涉及大量高维度数组,比较抽象,当时有些崩溃,不过还是挺过来,终于再一次理解绝地逢生这一句成语了。我的解决方法比较笨,但是比较实在。自己先用符号运算跑了一遍,结果证明正确,我才开始安安心心写R程序(又是一页辛酸史,一把鼻涕,一把泪,有空开个贴,好好和大家聊聊高维数组的符号运算)。当时,在论坛上逛,看了些初级书,许多人都说apply函数是个好东西,于是我就开始迷恋上了她了!现在想想,对象没有选对,害了自己几夜没睡好觉,端午放假,得补觉去喽!然而实战中,当时我还没有发现她的弊端,食堂午饭时间,还像别人大肆宣传她的好处,哎,现在希望那些人在我说话时开小车,不然太内疚了。
我和师弟,关于我的程序讨论了一个晚上,程序不长也不短,差不多400行吧(当然也包括多条注释,嘿嘿),我们达成一个共识,程序没错,但就找不出运算缓慢的原因。当天晚上,回宿舍,又开始狂逛论坛,结果很明显,还是一无所获。不知道是什么原因,凌晨干活异常清醒,我经常在这个时候想到比较好的解决方法,当然在一些大牛看来有些笨啦。于是我就利用system.time()函数一条一条测试程序运行时间,突然间发现apply函数即是原因所在,它就像绝大多数外围女,外观美丽,肚子里装的全是水(当然草也是备选啦,任凭你怎么想了),运算速度确实不敢恭维,特别是在我的数值优化中,一次迭代就要花去我两次上厕所的时间,没有夸张,事实就是如此。当时,我很快想到爱恨交织的for循环,没想到,她却我给我一个大大惊喜,速度能甩apply函数几条大街。哇咔咔,安心睡大觉啦!
高兴归高兴,但是我还是不想让她抛头露面,呵呵,躺在床上想了想。于是,今早,师兄答辩之时(当然是干完我的分内之事啦),又开始在论坛狂轰乱炸,这次结果显而易见,idea有了。colSums、colMeans、rowSums和rowMeans函数。为什么是这些函数了?论坛一些大牛指出这些函数是通过底层语言、c++和fortran编写的,运算速度较快,而apply函数是通过R自身的for循环构建的,对数值运算速度提升没啥帮助。很遗憾,本科我只学过VB和SAS,对底层语言一无所知,记忆中大二暑期帮同学借过一本C++,结果超期,罚了我30元,六顿盐水鸭的钱啊。言归正传,接下来说说我对col*,row*函数的运算时间测试,结果验证了大牛们的结论,她确实是最棒滴,此时我如释重负,终于找到一条最优路径,到达罗马城了。
今天废话太多了,不多说了,直接上程序,让大家品味下!对了,关于col*,row*函数的介绍,我写了一个比较粗糙的帖子,大家如果不介意,可以小逛下。链接地址:
https://bbs.pinggu.org/thread-3071374-1-1.html
哈哈,看到row*,col*函数威力了吗?显而易见吧,希望此帖能给大家编程,带来速度的大幅度提升(这里就不打火箭了)。呵呵,毕竟在论坛上折腾了几个星期了,不提升也不行哈!
接下来,我会写一个关于加速R矩阵运算的帖子,OpenBLAS,到时欢迎大家关注,一起交流学习。