Theory
All three methods have various realizations for various classes:
:nil?
:
# NilClass
def nil?
true
end
# Object
def nil?
false
end
:empty?
:
# String, Array
def empty?
if self.size == 0
true
else
false
end
end
:blank?
:
# FalseClass, NilClass
def blank?
true
end
# Object
def blank?
respond_to?(:empty?) ? empty? : !self
end
# TrueClass
def blank?
false
end
# String
def blank?
self !~ /[^[:space:]]/
end
As you may see the various classes implement various methods style. In case of String
class it takes time of a single Regexp
, in case of Object
, including Hash
, and Array
it takes time of call to :respond
and return a value nil
or not Object
. The seconds are just operations that takes time similar to :nil?
. :respond?
method checks the presense of the :empty?
method that takes theoretically slight more times than two times
to :empty?
.
Investigations
I wrote simple script that simulates the behaviour of those methods, and calculates execution time of them:
#! /usr/bin/env ruby
require 'benchmark'
obj = Object.new
array = []
empty_string = ''
non_empty_string = ' '
funcs =
[ proc { empty_string.empty? },
proc { non_empty_string.empty? },
proc { obj.nil? },
proc { nil.nil? },
proc { true },
proc { respond_to?(:empty?) ? empty? : !self },
proc { array.respond_to?(:empty?) ? array.empty? : !array },
proc { non_empty_string !~ /[^[:space:]]/ } ]
def ctime func
time = 0
1000.times { time += Benchmark.measure { 1000.times { func.call } }.to_a[5].to_f }
rtime = time /= 1000000
end
funcs.each {| func | p ctime( func ) }
And results:
# empty String :empty?
# 4.604020118713379e-07
# non_empty String :empty?
# 4.5903921127319333e-07
# Object :nil?
# 5.041143894195557e-07
# NilClass :nil?
# 4.7951340675354e-07
# FalseClass, NilClass, TrueClass :blank?
# 4.09862756729126e-07
# main :blank? ( respond_to returns false )
# 6.444177627563477e-07
# Array :blank? ( respond_to returns true )
# 6.491720676422119e-07
# String :blank?
# 1.4315705299377442e-06
As you may see, obvious champion from the end of table in case of speed is method :blank?
of String
class. It has execution time descreased in 3-4 times against an simple empty?
method of a class. Object's :blank?
method has only 1.5 times execution time degradation. Note, that :respond_to
method in it has just a few time to execute, becase as far as I see the ruby interpreter caches the result of its execution. So, conclusion. Try to avoid using String's .blank?
method.
Additional, if you need to know how to use the methods see here.