There is no real performance difference between "def" and "define_method"

You can define methods using def or define_method. In the real world, there is no performance difference.

define_method is most often used in metaprogramming, like so:

define_method :"#{attribute_name}_for_realsies?" do
  do_things
end

Methods defined via define_method are usually believed to have worse performance than those defined via def.
Hence, developers sometimes prefer using class_eval to define methods using def, like this:

class_eval "def #{attribute_name}_for_realsies?; do_things; end"

You can benchmark methods defined like this and will see that those defined via def actually do perform better. Basically, it ranks like this:

  1. def in your class' Ruby code
  2. def inside class_eval
  3. define_method

However, there is only significant difference for really short (or empty) methods. Once you add a bit of logic, all perform almost equally:

require 'benchmark/ips' # requires the 'benchmark-ips' gem

GC.disable

class Foo
  define_method("foo") { 10.times.map { "foo".length } }
  class_eval 'def bar; 10.times.map { "foo".length }; end'
  def baz; 10.times.map { "foo".length }; end
end

Benchmark.ips do |x|
  foo = Foo.new
  x.report("define_method") { foo.foo }
  x.report("def via class_eval") { foo.bar }
  x.report("def") { foo.baz }
end
Warming up --------------------------------------
       define_method    42.579k i/100ms
          class_eval    44.781k i/100ms
                 def    44.823k i/100ms
Calculating -------------------------------------
       define_method    512.248k (± 0.8%) i/s -      2.597M in   5.070730s
  def via class_eval    534.132k (± 0.5%) i/s -      2.687M in   5.030474s
                 def    535.329k (± 0.6%) i/s -      2.689M in   5.023994s

There is a bit more to all that, so I suggest you read the attached article by @tenderlove.
I could confirm his observations on Ruby 2.2 and 2.3, too.

All in all, don't worry about having define_method for your application's bit of metaprogramming.
It may matter for a framework like Rails, and for methods that are called really often, but that is not your everyday code.
Do keep in mind though that define_method's closures can prevent objects from being garbage collected.


Update in 2020: Note that, starting with Ruby 2.5, the performance gap between define_method and def actually increased a little, to a difference of about 5-10% for the example above (tested for 2.5.7, 2.6.5, 2.7.0). However, the above still applies: for your few lines of meta programming, you won't ever notice any difference. If you want to improve your code's performance, this is not the place to start.

Arne Hartherz