为什么是ruby';s版本的'tap'比C中实现的版本快?

为什么是ruby';s版本的'tap'比C中实现的版本快?,c,ruby,C,Ruby,请看一下这个公关 将C版本重写为简单ruby: def抽头 产量(自我) 自己 结束 使它工作得更快 流行的观点是用C编写的代码总是更快。这个方法在两个版本中都非常简单,为什么呢?这里的工作机制是什么 我正在研究Ruby的JIT和AFAIU,它包含了比C代码更多的几个额外步骤: 即标记化和解析。这种魔力从何而来?kernel.rb不是一个“普通”的Ruby文件。这是Ruby实现中的一个新特性,允许开发人员用Ruby编写某些部分 本文提供了关于这个特性的更多细节,但其中一个是性能:“有几个特性在

请看一下这个公关

将C版本重写为简单ruby:

def抽头
产量(自我)
自己
结束
使它工作得更快

流行的观点是用C编写的代码总是更快。这个方法在两个版本中都非常简单,为什么呢?这里的工作机制是什么

我正在研究Ruby的JIT和AFAIU,它包含了比C代码更多的几个额外步骤:
即标记化和解析。这种魔力从何而来?

kernel.rb
不是一个“普通”的Ruby文件。这是Ruby实现中的一个新特性,允许开发人员用Ruby编写某些部分

本文提供了关于这个特性的更多细节,但其中一个是性能:“有几个特性在C中比在Ruby中编写的慢”。这里的例子有异常处理和关键字参数,但C中的
tap
似乎也更快(可能是因为Ruby中的块处理速度比C快)

这个特性的一部分作用是在构建时将Ruby代码编译成字节码,并将其包含在生成的二进制文件中。这意味着在构建Ruby时,图中的前三个阶段(标记化、解析和编译)只发生一次。运行Ruby只需要计算预编译的字节码


您可能还想看看。

注意事项:这是基于意见的。。。半知情的情况

有趣的是,当逻辑使用单一语言(Ruby或C)时,一些编译时(或JIT)优化就变得可用,而桥接这两种语言会使这些优化变得不可能

例如,Ruby
.tap
方法创建一个块,并使用
yield
将对象传递给该块。但是如果我们知道整个逻辑(在JIT期间),我们就可以优化额外的函数调用,也许还可以优化
块的创建


…但是,如果两个不同的编译器需要在不同的时间编译代码(在编译Ruby时编译
tap
函数,并使用JIT编译
block
),那么这些优化就不可能了。

编译语言中的等效代码应该比解释语言中的代码更快。但是谁说我们实际上在处理等价的代码呢?C版本调用了
rb_yield()
,但这是如何实现的呢?如果被调用的函数实际上是用Ruby实现的,那么纯Ruby版本的速度会更快也就不足为奇了。如果你想比较苹果和苹果,写两个等价的应用程序:一个是纯C,另一个是纯Ruby,然后比较它们。@FelixG我从来没有说过它是等价的代码。你的观点很有意思,但你不会在幕后打电话给我吗?这是一个远离我的专业领域,因此这个问题。嗯,我想这是一个大问题。。。是
yield
调用
rb\u yield
,还是相反?是的,这将是答案的一部分……我意识到这并不能确切解释为什么Ruby比C更快(我对细节知之甚少),但这至少是完整答案的一部分。也许其他人会在另一个答案中填写缺失的部分。