【问题标题】:How much faster is C than R in practice?在实践中 C 比 R 快多少?
【发布时间】:2012-11-03 14:49:43
【问题描述】:

我在 R 中编写了一个 Gibbs 采样器,并决定将其移植到 C 中,看看它是否会更快。我看过的很多页面都声称 C 将快 50 倍,但每次我使用它时,它只比 R 快五六倍。我的问题是:这是可以预期的,还是有哪些我没有使用的技巧会使我的 C 代码比这快得多(比如使用矢量化如何加速 R 中的代码)?我基本上拿了代码并用 C 重写了它,用 for 循环替换矩阵运算,并使所有变量指针。

另外,从 R 程序员的角度来看,有没有人知道 C 语言的好资源? Matloff 有一本名为 The Art of R Programming 的优秀书籍,但它似乎是从已经了解 C 的人的角度编写的。

此外,当我的 C 代码在 Windows 的标准 R GUI 中运行时,屏幕往往会冻结。它不会崩溃;一旦代码完成运行,它就会解冻,但它会阻止我在 GUI 中做任何其他事情。有人知道我怎么能避免这种情况吗?我正在使用 .C() 调用该函数

【问题讨论】:

  • 除非您真正了解并理解 C,否则几乎没有性能提升。至于为什么会发生冻结,这都是关于线程的。我的猜测是 R 会在后台自动执行,而 C 绝对不会。
  • 视情况而定。只要您坚持原语,它们应该大致相同。当您编写三个嵌套的 {i,j,k} 循环来实现矩阵乘法时,C 会更快。 (如果你会使用矩阵/向量基元,则不是)
  • 补充@RichardJ.RossIII 所说的,永远记住,你不仅仅是在比较语言,你还在比较你在每种语言中的编程能力同时。很难区分为两个。
  • 这里是 Rcpp 的example,相对于甚至优化的 R 代码产生了巨大的加速,但最终它们被证明是由于 @wildplasser 指出的原语。在这种情况下,速度优势是因为 Rcpp 正在修改原始对象而不是修改复制的对象。 当 C(++) 代码执行与 R 代码相同的基本操作时,它同样快,但 C 允许更多地控制执行哪些操作。

标签: c r


【解决方案1】:

许多现有的帖子都有显式示例你可以运行,例如 Darren Wilkinson 在他的博客上有几篇文章用不同的语言分析这个,后来甚至在不同的硬件上(例如比较他的高将笔记本电脑连接到他的上网本和树莓派)。他的一些帖子是

在他的网站上还有更多——这些通常比较 C、Java、Python 等等。

现在,我还使用Rcpp 将它变成了一个版本——参见this blog post。今年夏天,我们还在 useR 上使用了相同的示例来比较 Julia、Python 和 R/C++,因此您应该找到很多其他示例和参考资料。 MCMC 被广泛使用,并且“容易挑选”以加快速度。

鉴于这些示例,请允许我补充一点,我不同意您之前收到的两个问题。速度将相同,在这样的示例中很容易做得更好,而您的 C/C++ 技能将主要决定好多少。

最后,一个经常被忽视的方面是 RNG 的速度非常重要。运行循环和添加东西很便宜——做“好”的平局不是,很多系统间的变化也来自于此。

【讨论】:

  • 感谢您通过真实示例链接到这些帖子!我过去看到的例子大多是人造的,例如。将前一百万个正整数相加。
  • 回复:你的最后一段,我真的看不到在 C 中生成统一随机数的好方法,所以我只是在开始之前在 R 中生成了所需数量的随机数,然后通过指向该数组的指针作为 C 函数的参数之一。我不确定这是否比在 C 中生成它们更好或更差?
  • 请参阅Writing R Extension, Section 6.3 或任何好的数值库的文档。 Rcpp 免费为您提供此功能,甚至是 vectorised 即一次调用和绘制的 N rngs 向量。以编译速度。
  • 你的意思是C要花很多时间去偷看和戳?应该避免这种情况吗?
  • 函数调用有开销。更少的总调用,更快的执行。
【解决方案2】:

关于 GUI 冻结,您可能需要不时致电 R_CheckUserInterruptR_ProcessEvents

【讨论】:

    【解决方案3】:

    我想说,如果做得好,C 比 R 快得多。

    您可以尝试一些简单的收获: 将编译器设置为优化以提高速度。 使用 -march 标志编译。 此外,如果您使用的是 VS,请确保您使用的是发布选项进行编译,而不是调试。

    【讨论】:

      【解决方案4】:

      您观察到的性能差异将取决于许多因素:您正在执行的操作类型、您编写 C 代码的方式、您使用的编译器级优化类型、您的目标 CPU 架构等。

      您可以编写基本的、草率的 C 语言,并获得一些可以正常工作并以相当高的效率运行的东西。您还可以针对您的目标 CPU 的独特特性微调您的代码 - 可能调用专门的汇编指令 - 并从代码中挤出最后一滴性能。您甚至可以编写比 R 版本运行速度明显的代码。 C 为您提供了很大的灵活性。这里的限制因素是您希望投入多少时间来编写和优化 C 代码。

      反之亦然(此处重复上一段,但交换“C”和“R”)。

      我并不想听起来很滑稽,但你的问题确实没有一个直截了当的答案。判断您的 C 版本的速度有多快的唯一方法是两种方式编写代码并对其进行基准测试。

      【讨论】:

      • "您甚至可以编写运行速度明显慢于 R 版本的代码。" -- 不,不是这样。
      猜你喜欢
      • 2010-09-13
      • 2016-07-23
      • 2014-05-04
      • 2011-04-17
      • 2018-04-10
      • 1970-01-01
      • 1970-01-01
      • 2019-11-18
      相关资源
      最近更新 更多