我应该学习Fortran还是C ++来扩展R?

我使用相当大的数据集进行机器学习(他们仍然适合内存),我写了一些R中的计算,我发现它们太慢了。 因此,我想用我将从R调用的编译代码replace程序的“关键部分”。我手中的一个示例问题是实现前向后向algorithm 。

我的问题是,我应该学习Fortran还是C ++来做到这一点? 我只需要使用数字向量或matrix。 我主要感兴趣的是哪种语言更容易学习和从R的界面,我并不在乎我的简历上看起来更好。

我已经阅读了R扩展手册,并通过一些简单的Fortran和C ++代码使用了内联包。 我目前的印象是Fortran95的学习会比较简单,虽然Rcpp包也很有趣。 我目前知道R,Python和Matlab。

如果你自己写所有的代码,那么这可能取决于你更喜欢哪种语言,或者可以学得更好/更快。 虽然Rcpp可能会让你更容易获取R对象到C ++。 而且,0.8.3中的最新增加在编译代码中给出了R-like向量expression式。

另一方面,如果您计划使用/重新使用/改编现有的库,那么我会仔细看一下例如 mloss.org ,看看哪种语言为您提供了最有用的机器学习库,并且也指导您的决定。

对我来说,C ++提供了相当有用的抽象概念,并且可以访问庞大的高质量代码库。 但其他人对Fortran满意。 这真的取决于你,并且有些人可以支持你身边的人。

我写了一些Fortran,很多Matlab,最近开始认真学习C ++。 我认为如果你使用Fortran而不是C ++,你将会更快地使用你的新语言。 我build议记住这一点:

  • 我猜想你要做的大部分数字是处理大数字的数组。 Fortran非常擅长这一点,它具有基本的语言结构和全数组操作的内在function(并不总是比循环更好的performance)。 C ++忽略了这些function,你必须自己编写它们,或者使用一个库(比如Boost)(比我更懂得的人强烈推荐)。
  • 许多使C ++成为大量应用程序types(模板,所有面向对象,指针,引用等等)的有吸引力的语言的function在您的域中并不是非常有用。 我怀疑,如果你需要做任何“聪明”的编程,你会在R中完成,而让Fortran简单的繁重。 Fortran也具有其中的大部分特性,但在Fortran社区中并没有被广泛使用。
  • Fortran的思维模式离Matlab的思路不远,所以从后者到前者的飞跃并不是很大。 现在我的观点是,学习足够多的Fortran在你的领域是有效率的,比学习足够多的C ++要快。
  • 至于Fortran和C ++的相对性能:除非你在前面进行测量,否则不要相信。 但是我认为你必须努力工作,聪明才智才能使C ++与Fortran的性能相匹配。 这当然可以完成,但是我认为这对程序员的技能要求更高。 Fortran编译器已经有超过50年的工作了,优化执行速度对我们Fortran程序员来说非常重要。

我无法评论R和Fortran或C ++集成的简易性

Fortran是我学习的第一个编程语言,从那以后我也拿起了C和一些C ++。 我的两分钱是,如果你需要快速加快一些matrix处理,一定要用Fortran。 原因是:

  • Fortran非常擅长高效地处理数字数据,尤其是当它存储在matrix或数组中时。 这种工作是语言的“甜蜜点”。

  • 由于Fortran对数值运算的重视程度较低,与C和C ++相比,它的学习曲线较低。 语言特点和学习方法较less,你不必处理指针。 如果你想要做的只是尽快加快一些计算并继续工作,这是一个很大的胜利。

  • multidimensional array和arrays操作是Fortran语言中的一等公民。 使用C或C ++,您需要担心使用外部库或编写函数/macros来提供相同的function。

另一方面,C和C ++确实更适合数值计算领域之外的通用编程任务。 如果你看到将来会有很多string操作的可能性,那么你可能想把时间花在Fortran以外的语言上。

更新

另一个重要的考虑是你的数据如何在R端存储和处理。 如果你使用fortran,那么你将不得不将数据以非常基本的方式传递到编译的例程中 – 标量,向量等。没有列表或花哨的对象。

由于R是用C语言实现的,因此有一个更丰富的接口可以让你直接传递任意R对象到C和C ++例程,然后返回任意R对象。 你也可以执行callback,允许你从编译的C代码中执行R函数。

我现在已经做了一些使用Fortran,C ++和R的实验,我想现在我至less有一半的时间来回答自己的问题。 我最终在Fortran和C ++中编写了diff函数(以及其他一些小testing),并从R中调用它。

对于初学者,我认为任何人面对这个问题应该阅读写R扩展 , Rcpp介绍和Rcpp常见问题 。

我现在已经发现了一些关于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中,它的速度和简洁是无与伦比的。

如果你在学术界,很多人仍然使用Fortran,所以这可能是一个很好的补充。 Fortran真的很擅长咀嚼数字。