2017-03-10 68 views
1

我想知道Ruby中的點和操作符表示法之間的區別。這裏有一些例子點和操作符表示法之間的區別Ruby

# Use dot notation to invoke a method 
"I'm thirty one characters long!".length 
# => 31 

# Use operator notation to invoke a method 
"Kit" + "tens!" 
# => "Kittens!" 

由於既調用方法並返回類似的對象,我懷疑點符號或運算符方法更有效。任何想法都表示讚賞。

+0

對於一些方法,你不會找到一個運營商的符號或點符號。例如'5.add(3)',除非你實現它。另一個例子是使用運算符調用.length方法 - 你不能這樣做。談到效率時,我們實際上應該有一些可以比較的東西。如果你提供了一個兩種方法的例子,我們可以做到這一點。 –

+0

首先想到的是:基準測試(ruby甚至有內建的基準測試模塊) – Jokester

+0

「既然都調用方法並返回類似的對象,我懷疑點符號或運算符方法是更有效的。」 - 我不遵循你的邏輯:你基本上在說「因爲兩者完全相同,所以必須更有效率」。但這沒有意義:如果他們都做同樣的事情,你會期望他們是完全一樣的效率。 –

回答

4

[...]如果我們調用使用點.符號上對象的方法,然後在那裏是2 + 3 * 4點?

訣竅是:Ruby爲你無聲添加它們。如果你寫了下面的代碼:

number = 2 + 3 * 4 

然後將Ruby翻譯這以下幾點:

number = 2.+(3.*(4)) 

- Operators are methods | Ruby for Beginners

至於性能上的差異:

# bmbm_dot_vs_operators.rb 
require "benchmark" 

Benchmark.bmbm do |x| 
    x.report("dots") { 2.+(3.*(4)) } 
    x.report("operators") { 2 + 3 * 4 } 

    x.report("operators") { 4 + 2 * 3 } 
    x.report("dots") { 4.+(2.*(3)) } 
end 

當我的系統上運行(MacBook P ro(Retina,15英寸,2013年末)),產生如下結果

$ ruby bmbm_dot_vs_operators.rb 
Rehearsal --------------------------------------------- 
dots  0.000000 0.000000 0.000000 ( 0.000005) 
operators 0.000000 0.000000 0.000000 ( 0.000002) 
operators 0.000000 0.000000 0.000000 ( 0.000002) 
dots  0.000000 0.000000 0.000000 ( 0.000002) 
------------------------------------ total: 0.000000sec 

       user  system  total  real 
dots  0.000000 0.000000 0.000000 ( 0.000002) 
operators 0.000000 0.000000 0.000000 ( 0.000002) 
operators 0.000000 0.000000 0.000000 ( 0.000002) 
dots  0.000000 0.000000 0.000000 ( 0.000002) 

結果不確定。

在使用內聯運算符而不是點方法等價物時,性能幾乎沒有可測量的差異。

此外,第一個操作始終是最慢的,因此爲什麼它包含多次用於比較基準測試順序。

參考文獻:

+1

謝謝@sonna。你的解釋非常好。 – aprogrammer

0

TL;博士:操作符號是點標記語法糖。我不希望有任何明顯的性能差異。

如果你看一下Ruby's grammar,你會發現如下:

call_bin_op(recv,id,arg1) call_bin_op_gen(parser, (recv),(id),(arg1)) 

這基本上說,二進制運算符,例如在你的榜樣+,有一個接收器,一個ID(認爲的,作爲CRuby了符號)和參數,就像使用一個參數的方法調用一樣。

如果你再看看call_bin_op_gen,你會看到,它實際上轉化爲一個電話:

static NODE * 
call_bin_op_gen(struct parser_params *parser, NODE *recv, ID id, NODE *arg1) 
{ 
    value_expr(recv); 
    value_expr(arg1); 
    return NEW_CALL(recv, id, NEW_LIST(arg1)); 
}