Ruby on rails Ruby/Rails从模型内部显式/隐式常量调用。基准/性能怀疑

Ruby on rails Ruby/Rails从模型内部显式/隐式常量调用。基准/性能怀疑,ruby-on-rails,ruby,activerecord,Ruby On Rails,Ruby,Activerecord,我对同一类中定义和使用的常量的用法有疑问 class Car CON = "xxx" def some_method puts CON puts Car::CON end end 仅通过编写CON来访问CON是否会提高性能,而不是Car::CON。我知道,如果在同一个类中定义了它,那么通过CON访问它是一种很好的做法,但我怀疑它是否也能提高性能 另外,如果我们查看Rails,会使用 Car.where(...) 导致任何性能问题,而不

我对同一类中定义和使用的常量的用法有疑问

class Car
  CON = "xxx"
  def some_method    
    puts CON
    puts Car::CON    
  end       
end
仅通过编写
CON
来访问
CON
是否会提高性能,而不是
Car::CON
。我知道,如果在同一个类中定义了它,那么通过
CON
访问它是一种很好的做法,但我怀疑它是否也能提高性能

另外,如果我们查看Rails,会使用

Car.where(...)
导致任何性能问题,而不仅仅是使用

where(...)
车型内部开始


谢谢

我看不出有什么不同
Car.where
where
只是同一方法的显式和隐式调用。由于作用域的原因,有两种变体(
public
/
private
/
protected
),您只能隐式调用
private
方法

关于常数,我刚刚检查了一下,下面是结果(有时1次调用显示更多,有时2次调用显示更多,但每次都几乎相同):


因此,对于这两个问题,答案是相同的:性能没有差异。

以下是我为验证这一点所做的:

test.rb

require 'benchmark'
class Car
  CON = "xxx"
  def self.some_method
    time1 = Benchmark.measure do
      puts CON
    end
    time2 = Benchmark.measure do
      puts Car::CON
    end
    puts "Time1"
    puts time1
    puts "Time2"
    puts time2
  end
  Car::some_method
end
输出:

xxx
xxx
Time1
  0.000000   0.000000   0.000000 (  0.000078)
Time2
  0.000000   0.000000   0.000000 (  0.000025)
xxx
xxx
Time1
  0.000000   0.000000   0.000000 (  0.000051)
Time2
  0.000000   0.000000   0.000000 (  0.000022)
看起来
Car::CON
CON
快。但为了确保我交换了他们在代码中的位置。(即时间1现在表示
Car::CON
,时间2表示
CON

输出:

xxx
xxx
Time1
  0.000000   0.000000   0.000000 (  0.000078)
Time2
  0.000000   0.000000   0.000000 (  0.000025)
xxx
xxx
Time1
  0.000000   0.000000   0.000000 (  0.000051)
Time2
  0.000000   0.000000   0.000000 (  0.000022)
正如您所看到的,第一次加载常量总是需要更多的时间。因此,我们不能得出任何结论。另外,输出2似乎表明
Car::CON
速度更快,但如果您运行该脚本几次,就会知道您不能肯定地说这一点

我的建议是使用
Car::CON
,因为它比
CON
更具可读性。还可以使用
Car::CON
从外部访问常量,使其更标准

在我的模型中,我也做到了:

  def self.test_method
    time1 = Benchmark.measure do
      where(:user_id => 1)
    end
    time2 = Benchmark.measure do
      self.where(:user_id => 1)
    end
    puts "Time1"
    puts time1
    puts "Time2"
    puts time2
  end
输出#1:

输出#2(在交换
where
self.where
之后):

再次显示相同的结果。这意味着它们在性能方面是相同的


在这种情况下,我也建议使用
self.where
,因为它更具可读性。

我从未见过
p::CON
。你是说
Car::CON
?那一定是打字错误。我编辑了这个问题。谢谢,这是缓存。它们是一样的。交换
where(:user\u id=>1)
self.where(:user\u id=>1)
,您将看到相反的结果results@RustamA.Gasanov我在第一次回答时不小心忽略了这一点。但我已经编辑了我的答案。请检查。您的ruby版本和系统规格是什么?@dknight我的笔记本电脑上有多个ruby版本,没有区别,我在1.9.3和2.2.0上测试了这个版本,收到了相同的结果。@rustam-a-gasanov您能试试Shivam的代码,看看有什么区别吗?我不知道基准测试的内部结构,但我们可以试试看。
Time1                                                                                                                                                                                                                                                                          
  0.000000   0.000000   0.000000 (  0.000348)                                                                                                                                                                                                                                  
Time2                                                                                                                                                                                                                                                                          
  0.000000   0.000000   0.000000 (  0.000187)