Feature #10396
closedIncrease instance variable retrieval performance by removing -w/$VERBOSE warning
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