2012-08-22 43 views
5

使用红宝石1.9.2p290(2011-07-09修订版32553)[x86_64-linux]更快在红宝石Fixnum乘法?

我一直在做很多分析,它引起了我的注意,ruby Fixnum乘法非常慢。

通过一些分析,我了解到这是(部分),因为每次调用Fixnum#*都涉及到6个调用Kernel#kind_of

我知道你可以编写C扩展,但是这些乘法会遍及整个代码。那么,有没有办法避免Ruby内部的这种开销?

感谢

+0

这很有趣。你用什么来分析代码?我会猜想本地Ruby乘法相对有效。 –

+0

@BlakeTaylor我正在使用ruby-prof – user844942

回答

5

我严重怀疑,这些测量结果是准确的,有以下几个原因:

  1. 你没有说明您正在使用的红宝石的实施,但ruby-prof是一个Ruby分析器。它描述Ruby代码。我不知道Ruby的执行情况,其中Fixnum#*是Ruby代码。在MRI中,YARV,MRuby和tinyrb是C代码,Rubinius是C++代码,MacRuby是Objective-C代码,JRuby和XRuby是Java代码,RubyGoLightly是Go代码,IronRuby和Ruby。 NET是C#代码,在MagLev和SmallRuby中是Smalltalk代码,在Cardinal中是PASM代码。 ruby-prof可以剖析Ruby代码,它不能剖析C,C++,Objective-C,Java,C#,Go,Smalltalk或PASM。只有Ruby。因此,它只是不能简介Fixnum#*

  2. 不需要Fixnum#*多次检查课程。它知道selfFixnum,因为否则该调用首先不会被调度到Fixnum#*方法,因此它只需要检查参数。它还需要检查结果是否适合Fixnum,但它会在内部完成,而不是通过调用kind_of?(事实上,这甚至没有意义:为了能够调用方法根据乘法的结果,它首先必须构造结果对象,并且为了构造结果对象,它将不得不知道它是否适合于Fixnum)。

  3. 它不会通过调用kind_of?来进行类检查,并通过整个Ruby方法查找和方法调度机制。这是Ruby实现的内部功能,它可以访问所有的私有内部实现细节,它只是直接检查类或调用一些内部翻译功能,而不是Ruby的方法kind_of?

  4. 我检查的Fixnum#*的实施各种流行的Ruby实现,并没有发现任何调用kind_of?。不幸的是,你没有说明你正在使用哪个Ruby实现。

+0

感谢您的回复。我当然可能是错的。这里就是我看到我的探查输出: '23.52%9.49%5.17 2.08 0.00 3.08 808533#长整数*'' 2.27 2.27 0.00 0.00五百三十五万五千五百三十四分之四百八十五万一千一百九十八内核#kind_of' 我不知道,如果你熟悉ruby-prof图形输出,但方法名称下方的行是从该方法调用的方法。 我不知道我在使用什么实现。它要么来自Ubuntu,要么来自apt-get。你知道我能找到什么吗? – user844942

+1

你说得对,顺便说一句。如果你对发生的事情感到好奇,看看我的答案。 – user844942

2

那么,我想我想通了。我正在使用GSL库,并且它看起来修补了Fixnum#*代码,您可以在这里看到:https://github.com/romanbsd/rb-gsl/blob/master/lib/gsl/oper.rb#L15

此代码包括...等待它... 6个调用内核#kind_of?在一个大的醇'或'声明。

我不会假装完全理解它是如何工作的或它为什么会发生,但代码路径与探查器输出完全匹配。