我使用相当大的数据集(它们仍然适合内存)使用机器学习,我在R中编写了一些计算,我觉得它太慢了.因此,我想用我将从R调用的编译代码替换程序的"关键部分".我手头的一个示例问题是实现前向 - 后向算法.
我的问题是我是否应该学习Fortran或C++来做到这一点?我只需要使用数字向量或矩阵.我主要感兴趣的是哪种语言更容易学习和R界面,我真的不关心哪一个在我的简历上看起来更好.
我已经阅读了R扩展手册,并使用内联包使用一些简单的Fortran和C++代码.我目前的印象是Fortran95会更容易学习,虽然Rcpp包看起来也很有趣.我目前知道R,Python和Matlab.
我写了很多Fortran,很多Matlab,最近开始认真学习C++.我认为如果你使用Fortran而不是C++,你会更快地使用新语言.我建议记住这一点:
我想你要做的大部分数字运算都是处理大数字数组.Fortran非常擅长这一点,它具有基本的语言结构和整个数组操作的内在函数(并不总是比循环更好的表现).C++错过了这些功能,你要么自己编程,要么使用像Boost这样的库(强烈推荐比我更了解的人).
许多使C++成为各种应用程序类型(模板,所有OO内容,指针,引用等功能)的有吸引力的语言的功能在您的域中并不十分有用.我怀疑,如果你需要做任何"聪明"的编程,你将在R中进行,让Fortran进行简单的繁重工作.Fortran也具有大部分功能,但它们在Fortran社区中的使用并不广泛.
Fortran的思维方式与Matlab的思维方式相差不远,所以从后者到前者的飞跃并不是很大.现在,我的观点是,学习足够的Fortran在你的领域中提高效率比学习足够的C++要快.
至于Fortran和C++的相对性能:除非你面前有测量,否则不要相信.但我认为你必须努力工作才能让C++与Fortran性能相匹配.它当然可以完成,但我认为它对程序员的技能要求更高.Fortran编译器已经有超过50年的工作经验,并且执行速度的优化对我们的Fortran程序员来说非常重要.
我完全不能评论集成R和Fortran或C++的简易性
如果您自己编写所有代码,那么它可能取决于您更喜欢哪种语言,或者可以更好/更快地学习.虽然Rcpp可能会让你更容易将R对象转换为C++并且更容易返回.此外,0.8.3中最新增加的内容为编译代码提供了R-like类型的向量表达式.
另一方面,如果您计划使用/重新使用/改编现有的库,那么我会好好看看例如 mloss.org,看看哪种语言为您提供了最有用的机器学习库,并指导您做出决定.
对我来说,C++提供了相当有用的抽象加上获得的一般质量好的一个巨大的代码库.但其他人对Fortran满意.这实际上取决于你,以及一些能够给予支持的人.
Fortran是我学过的第一种编程语言,从那以后我也选择了C和一些C++.我的两分钱是,如果你需要快速加速一些矩阵处理,肯定会选择Fortran.原因是:
Fortran非常擅长有效处理数值数据,特别是当它存储在矩阵或数组中时.这种工作是语言的"甜蜜点".
由于Fortran对数值运算的关注较为狭窄,因此与C和C++相比,它的学习曲线较低.学习语言功能和怪癖的次数较少,您无需处理指针.如果您想要做的就是尽快加快计算并继续工作,这是一个巨大的胜利.
多维数组和数组操作是Fortran语言中的一等公民.使用C或C++,您需要担心使用外部库或编写函数/宏来提供相同的功能.
另一方面,C和C++明显更适合于数值计算领域之外的通用编程任务.如果你看到未来有很多字符串操作的可能性,那么你可能想把时间用在Fortran以外的语言上.
更新
另一个重要的考虑因素是如何在R端存储和处理数据.如果您使用fortran,则必须以非常基本的方式将数据传递到已编译的例程中 - 标量,向量等.没有列表或花哨的对象.
由于R是用C实现的,因此有一个更丰富的接口可以让你直接将任意R对象传递给C和C++例程,然后返回任意R对象.您还可以执行回调,允许您从已编译的C代码中执行R函数.
我现在已经做了一些使用Fortran,C++和R的实验,我想我现在至少已经准备好回答我自己的问题.我最终在Fortran和C++中编写diff函数(以及其他一些小测试)并从R调用它.
对于初学者,我认为任何遇到这个问题的人都应该阅读写作R扩展,Rcpp介绍和Rcpp FAQ.
我现在已经发现了一些关于连接R代码的重要观点,这些代码尚未在答案中介绍:
带内联包的Rcpp使得从R调用C++非常容易,甚至负责编译扩展(参见Rcpp FAQ),你可以指定你不想进入函数的所有东西以及你想要得到的东西.
使用Rcpp和RcppArmadillo可以编写高效的计算并使用非常基本的C++知识从R中轻松调用它们.
Fortran".Fortran"的R接口更受限制,您需要使用子程序来完成它,并且您需要传递所有参数,因为您不想离开.那是(据我所知)你需要预先分配并将结果向量(或数组)传递给子程序,子程序也返回所有参数.这并不困难,但更容易出错,乏味且有限.
如果您不想编写便携包,则需要使用F77,请参阅此处.
因此,作为一个结论:对于我需要编写的Fortran和C++(使用Armadillo)似乎〜同样容易(或困难),但使用Rcpp来连接R的C++代码要容易得多.
Fortran是HPC的Java.您可以用C++编写非常高效的程序,但只要它适合数字运算,就可以更容易地在Fortran中编写相同的程序.没有人会认真地在Fortran中编写GUI应用程序,但在HPC中,它在速度和简洁性方面是无与伦比的.