Skip to content

Instantly share code, notes, and snippets.

@wojtha
Last active April 12, 2020 17:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save wojtha/d1de33d8e83a0098d16d to your computer and use it in GitHub Desktop.
Save wojtha/d1de33d8e83a0098d16d to your computer and use it in GitHub Desktop.
Seeking for the fastest "to boolean" implementation in ruby. See https://coderwall.com/p/inziba
require 'benchmark'
require 'set'
def to_boolean_eq(value)
value == true || value == 'true' || value == 1 || value == '1' || value == 't'
end
def to_boolean_equal(value)
value === true || value === 'true' || value === 1 || value === '1' || value === 't'
end
def to_boolean_when(value)
case value
when true, 'true', 1, '1', 't' then true
else false
end
end
def to_boolean_array(value)
[true, 'true', 1, '1', 't'].include?(value)
end
def to_boolean_set(value)
Set.new([true, 'true', 1, '1', 't']).include?(value)
end
TRUE_VALS_ARY = [true, 'true', 1, '1', 't']
def to_boolean_array_cached(value)
TRUE_VALS_ARY.include?(value)
end
TRUE_VALS_SET = Set.new([true, 'true', 1, '1', 't'])
def to_boolean_set_cached(value)
TRUE_VALS_SET.include?(value)
end
def benchmark(value, iterations = 100_000)
puts <<-BAN
------------------------------------------------
Benchmark for #{value.class} '#{value}'
BAN
Benchmark.bm(27) do |bm|
bm.report(:to_boolean_eq) do
iterations.times do
to_boolean_eq(value)
end
end
bm.report(:to_boolean_equal) do
iterations.times do
to_boolean_equal(value)
end
end
bm.report(:to_boolean_when) do
iterations.times do
to_boolean_when(value)
end
end
bm.report(:to_boolean_array) do
iterations.times do
to_boolean_array(value)
end
end
bm.report(:to_boolean_set) do
iterations.times do
to_boolean_set(value)
end
end
bm.report(:to_boolean_array_cached) do
iterations.times do
to_boolean_array(value)
end
end
bm.report(:to_boolean_set_cached) do
iterations.times do
to_boolean_set(value)
end
end
end
end
benchmark(true)
benchmark('t')
benchmark('false')
# $ ruby bench_boolean.rb
# ------------------------------------------------
# Benchmark for TrueClass 'true'
# user system total real
# to_boolean_eq 0.010000 0.000000 0.010000 ( 0.010257)
# to_boolean_equal 0.010000 0.000000 0.010000 ( 0.010859)
# to_boolean_when 0.010000 0.000000 0.010000 ( 0.011311)
# to_boolean_array 0.050000 0.000000 0.050000 ( 0.050133)
# to_boolean_set 0.370000 0.000000 0.370000 ( 0.369136)
# to_boolean_array_cached 0.050000 0.000000 0.050000 ( 0.050569)
# to_boolean_set_cached 0.380000 0.000000 0.380000 ( 0.386393)
# ------------------------------------------------
# Benchmark for String 't'
# user system total real
# to_boolean_eq 0.060000 0.000000 0.060000 ( 0.055832)
# to_boolean_equal 0.060000 0.000000 0.060000 ( 0.060313)
# to_boolean_when 0.040000 0.000000 0.040000 ( 0.043082)
# to_boolean_array 0.100000 0.000000 0.100000 ( 0.093800)
# to_boolean_set 0.370000 0.000000 0.370000 ( 0.369338)
# to_boolean_array_cached 0.090000 0.000000 0.090000 ( 0.089801)
# to_boolean_set_cached 0.380000 0.000000 0.380000 ( 0.389204)
# ------------------------------------------------
# Benchmark for String 'false'
# user system total real
# to_boolean_eq 0.060000 0.000000 0.060000 ( 0.053945)
# to_boolean_equal 0.050000 0.000000 0.050000 ( 0.053510)
# to_boolean_when 0.040000 0.000000 0.040000 ( 0.041162)
# to_boolean_array 0.090000 0.000000 0.090000 ( 0.087059)
# to_boolean_set 0.360000 0.000000 0.360000 ( 0.365578)
# to_boolean_array_cached 0.090000 0.000000 0.090000 ( 0.087375)
# to_boolean_set_cached 0.380000 0.000000 0.380000 ( 0.384433)
module Conversions
module_function
def Boolean(value)
case value
when true, 'true', 1, '1', 't' then true
when false, 'false', nil, '', 0, '0', 'f' then false
else
raise ArgumentError, "invalid value for Boolean(): \"#{value.inspect}\""
end
end
end
require 'spec_helper'
describe Conversions do
describe '.Boolean' do
context 'given truthy values' do
[true, 'true', 1, '1', 't'].each do |val|
it "returns true for '#{val}' (#{val.class})" do
expect( Conversions.Boolean(val) ).to be true
end
end
end
context 'given falsey values' do
[false, 'false', nil, '', 0, 0.0, '0', 'f'].each do |val|
it "returns false for '#{val}' (#{val.class})" do
expect( Conversions.Boolean(val) ).to be false
end
end
end
context 'given not meaningful values' do
['fail', 2, -1, 0.1].each do |val|
it "raises ArgumentError for '#{val}' (#{val.class})" do
expect{ Conversions.Boolean(val) }.to raise_error ArgumentError
end
end
end
end
end
Conversions
.Boolean
given falsey values
returns false for 'false' (String)
returns false for '0.0' (Float)
returns false for '' (NilClass)
returns false for '0' (Fixnum)
returns false for '' (String)
returns false for 'false' (FalseClass)
returns false for '0' (String)
returns false for 'f' (String)
given truthy values
returns true for 'true' (String)
returns true for 't' (String)
returns true for '1' (Fixnum)
returns true for '1' (String)
returns true for 'true' (TrueClass)
given not meaningful values
raises ArgumentError for '2' (Fixnum)
raises ArgumentError for 'fail' (String)
raises ArgumentError for '-1' (Fixnum)
raises ArgumentError for '0.1' (Float)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment