Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

defined? vs instance_variable_defined?/const_defined?/etc #325

Open
fatkodima opened this issue Dec 29, 2022 · 0 comments · May be fixed by #333
Open

defined? vs instance_variable_defined?/const_defined?/etc #325

fatkodima opened this issue Dec 29, 2022 · 0 comments · May be fixed by #333

Comments

@fatkodima
Copy link
Contributor

fatkodima commented Dec 29, 2022

defined? (besides that is universal and shorter) is 20% faster than other specialized _defined? methods. But, obviously, can be applied only to self/nil receiver.

# frozen_string_literal: true

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"
  git_source(:github) { |repo| "https://github.com/#{repo}.git" }
  gem "benchmark-ips"
end

class Foo
  def initialize
    @value = 1
  end

  def foo
    defined?(@value)
  end

  def bar
    instance_variable_defined?(:@value)
  end
end

f = Foo.new

Benchmark.ips do |x|
  x.report("defined?") do
    f.foo
  end

  x.report("instance_variable_defined?") do
    f.bar
  end

  x.compare!
end
Warming up --------------------------------------
            defined?   934.424k i/100ms
instance_variable_defined?
                       780.344k i/100ms
Calculating -------------------------------------
            defined?      9.318M (± 0.5%) i/s -     46.721M in   5.014049s
instance_variable_defined?
                          7.794M (± 0.3%) i/s -     39.017M in   5.005796s

Comparison:
            defined?:  9318309.9 i/s
instance_variable_defined?:  7794499.8 i/s - 1.20x  (± 0.00) slower
== disasm: #<ISeq:foo@benchmark2.rb:16 (16,2)-(18,5)> (catch: FALSE)
0000 putnil                                                           (  17)[LiCa]
0001 defined                                instance-variable, :@value, "instance-variable"
0005 leave                                                            (  18)[Re]

== disasm: #<ISeq:bar@benchmark2.rb:20 (20,2)-(22,5)> (catch: FALSE)
0000 putself                                                          (  21)[LiCa]
0001 putobject                              :@value
0003 opt_send_without_block                 <calldata!mid:instance_variable_defined?, argc:1, FCALL|ARGS_SIMPLE>
0005 leave                                                            (  22)[Re]
@fatkodima fatkodima linked a pull request Jan 21, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants