Skip to content

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

@fatkodima

Description

@fatkodima

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:[email protected]:16 (16,2)-(18,5)> (catch: FALSE)
0000 putnil                                                           (  17)[LiCa]
0001 defined                                instance-variable, :@value, "instance-variable"
0005 leave                                                            (  18)[Re]

== disasm: #<ISeq:[email protected]: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]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions