Project

General

Profile

Feature #10396

Increase instance variable retrieval performance by removing -w/$VERBOSE warning

Added by jeremyevans0 (Jeremy Evans) over 5 years ago. Updated over 5 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
[ruby-core:65786]

Description

This patch removes the "instance variable @foo not initialized" -w/$VERBOSE warning, increasing instance variable retrieval performance. ruby doesn't warn about uninitialized instance variable retrieval by default, only in -w/$VERBOSE mode. This warning causes a performance hit for all code, even if the warning is not printed, and it isn't by default.

Requiring the setting of instance variables to nil to avoid warnings in -w/$VERBOSE mode hurts ruby performance. Consider these two approaches:

# initialized
class A
  def initialize
    @c = @d = @e = @f = nil
  end
  def b
    @c || @d || @e || @f
  end
end

# not initialized
class A
  def initialize
    # nothing
  end
  def b
    @c || @d || @e || @f
  end
end

Using the following benchmark:

Benchmark.measure{10000000.times{A.new.b}}

# before - initialized
7.450000   0.000000   7.450000 (  7.453981)
7.240000   0.000000   7.240000 (  7.231404)
7.240000   0.000000   7.240000 (  7.242685)

# before - not initialized
3.350000   0.000000   3.350000 (  3.350715)
3.450000   0.000000   3.450000 (  3.448517)
3.430000   0.000000   3.430000 (  3.431949)

# after - initialized
6.650000   0.000000   6.650000 (  6.657332)
6.690000   0.000000   6.690000 (  6.686116)
6.660000   0.000000   6.660000 (  6.660838)

# after - not initialized
2.820000   0.000000   2.820000 (  2.817551)
2.770000   0.000000   2.770000 (  2.771170)
2.670000   0.000000   2.670000 (  2.669535)

With this patch, you get a 8% increase for the initialized version and a 25% increase for the not initialized version. However, if you want to be warning free in -w/$VERBOSE mode, this patch results in a 170% increase in performance, since you can switch from the initialized version to the not initialized version.

Note that if you use attr_reader, the method it defines do not warn for uninitialized instance variables. However, calling a method is slower than direct instance variable access:

# not initialized - attr_reader
class A
  def initialize
  end
  attr_reader :c, :d, :e, :f
  def b
    c || d || e || f
  end
end

# before - not initialized - attr_reader
3.600000   0.000000   3.600000 (  3.597794)
3.640000   0.000000   3.640000 (  3.645631)
3.570000   0.000000   3.570000 (  3.570119)

# after - not initialized - attr_reader
3.240000   0.000000   3.240000 (  3.246522)
3.220000   0.000000   3.220000 (  3.217739)
3.220000   0.000000   3.220000 (  3.219133)

I think the performance benefits of the patch outweigh the costs (the loss of the warning for uninitialized instance variables in -w/$VERBOSE mode).

$ ruby -v
ruby 2.2.0dev (2014-10-18) [x86_64-openbsd5.6]


Files

ruby.diff (1.06 KB) ruby.diff jeremyevans0 (Jeremy Evans), 10/19/2014 01:11 AM

Updated by nobu (Nobuyoshi Nakada) over 5 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

Applied in changeset r48035.


variable.c, vm_insnhelper.c: improve performance

  • variable.c (rb_ivar_get), vm_insnhelper.c (vm_getivar): improve instance variable retrieval performance by checking ruby_verbose before call of rb_warning and evaluation of its argument. [ruby-core:65786] [Feature #10396]

Also available in: Atom PDF