Last active
April 12, 2020 17:49
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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