Project

General

Profile

Feature #13602

Optimize instance variable access if $VERBOSE is not true when compiling

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

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:81400]

Description

This patch optimizes instance variable lookup in the case the $VERBOSE
is not true when compiling. If $VERBOSE is not true when compiling
code, it makes the instance variable access use an optimized VM
instruction that does not check $VERBOSE at runtime.

This does not change the behavior if $VERBOSE is not changed at runtime,
only when $VERBOSE is not true when compiling the code, but is true when
running it. In the case where $VERBOSE is not true when compiling and
true at runtime, this patch makes ruby no longer emit the warning
message.

Using a similar benchmark as #10396:

require 'benchmark/ips'

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

Benchmark.ips do |x|
  x.report("A.new.b"){A.new.b}
  x.report("A.allocate.b"){A.allocate.b}
end

Before Patch:

             A.new.b    347.380k (_ 1.7%) i/s -      1.741M
        A.allocate.b    862.884k (_ 0.4%) i/s -      4.317M

             A.new.b    338.830k (_ 1.7%) i/s -      1.706M
        A.allocate.b    848.036k (_ 0.4%) i/s -      4.254M

             A.new.b    344.167k (_ 1.7%) i/s -      1.731M
        A.allocate.b    826.183k (_ 0.4%) i/s -      4.138M

After Patch:

             A.new.b    350.251k (_ 1.7%) i/s -      1.753M
        A.allocate.b    900.666k (_ 0.7%) i/s -      4.512M

             A.new.b    349.868k (_ 1.7%) i/s -      1.760M
        A.allocate.b    898.292k (_ 0.4%) i/s -      4.505M

             A.new.b    349.690k (_ 1.7%) i/s -      1.751M
        A.allocate.b    888.524k (_ 0.6%) i/s -      4.444M

So about a 1-2% increase in the case where instance variables are
already initialized, and about 5-7% increase in the case where
instance variables are not initialized.


Files

History

Updated by nobu (Nobuyoshi Nakada) over 2 years ago

It doesn't look nice to assume $VERBOSE doesn't change.
And seems that benchmark includes allocation and initialization.

Updated by jeremyevans0 (Jeremy Evans) over 2 years ago

OK, here's a slightly revised benchmark that just measures
instance variable access without allocation:

require 'benchmark/ips'

$stderr.reopen('/dev/null')
class A
  def initialize
    @c = @d = @e = @f = nil
  end
  def b
    @c || @d || @e || @f
  end
end

n = A.new
a = A.allocate

Benchmark.ips do |x|
  x.report("new.b"){n.b}
  x.report("allocate.b"){a.b}
end

Before:

               new.b      1.597M (_ 0.3%) i/s -      7.998M
          allocate.b      1.553M (_ 0.8%) i/s -      7.782M

               new.b      1.635M (_ 0.7%) i/s -      8.196M
          allocate.b      1.590M (_ 0.5%) i/s -      7.970M

               new.b      1.607M (_ 0.2%) i/s -      8.051M
          allocate.b      1.552M (_ 0.3%) i/s -      7.776M

After:

               new.b      1.703M (_ 0.9%) i/s -      8.521M
          allocate.b      1.788M (_ 0.3%) i/s -      8.935M

               new.b      1.773M (_ 0.7%) i/s -      8.884M
          allocate.b      1.812M (_ 0.2%) i/s -      9.062M

               new.b      1.772M (_ 1.2%) i/s -      8.875M
          allocate.b      1.809M (_ 0.3%) i/s -      9.046M

So about an 8% improvement for initialized instance variables,
and 14% improvement for uninitialized instance variables.

I do realize that this breaks backwards compatibility slightly.
If the performance benefits do not justify that, this can be
closed.

Updated by ko1 (Koichi Sasada) about 2 years ago

  • Status changed from Open to Feedback

It seems 5% can not justify this kind of optimization.

We can use your technique when we revert all of optimized instructions when $VERBOSE was changed. But I'm not sure this kind of modification is valuable than implementation cost (it can be).

Updated by jeremyevans0 (Jeremy Evans) about 2 years ago

  • Status changed from Feedback to Rejected

ko1 (Koichi Sasada) wrote:

It seems 5% can not justify this kind of optimization.

We can use your technique when we revert all of optimized instructions when $VERBOSE was changed. But I'm not sure this kind of modification is valuable than implementation cost (it can be).

I think this can be rejected then. Reverting the optimized instructions would require compiling both the unoptimized version and the optimized version and keeping both in memory, or recompiling on a change to $VERBOSE, neither of which seems like a reasonable approach considering the modest performance improvement.

Also available in: Atom PDF