Created
August 2, 2021 04:56
-
-
Save baweaver/c35262cdd31f583e014b7e47e8848664 to your computer and use it in GitHub Desktop.
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/ips' | |
class TimeFilter | |
attr_reader :start, :finish | |
def initialize(start, finish) | |
@start = start | |
@finish = finish | |
end | |
def to_proc | |
proc do |value| | |
next false if start && value < start | |
next false if finish && value > finish | |
true | |
end | |
end | |
end | |
class TimeFilterLocal | |
attr_reader :start, :finish | |
def initialize(start, finish) | |
@start = start | |
@finish = finish | |
end | |
def to_proc | |
proc do |value| | |
start = self.start | |
finish = self.finish | |
next false if start && value < start | |
next false if finish && value > finish | |
true | |
end | |
end | |
end | |
class TimeFilterHoistedLocal | |
attr_reader :start, :finish | |
def initialize(start, finish) | |
@start = start | |
@finish = finish | |
end | |
def to_proc | |
start = self.start | |
finish = self.finish | |
proc do |value| | |
next false if start && value < start | |
next false if finish && value > finish | |
true | |
end | |
end | |
end | |
class TimeFilterProcBranch | |
attr_reader :start, :finish | |
def initialize(start, finish) | |
@start = start | |
@finish = finish | |
end | |
def to_proc | |
start = self.start | |
finish = self.finish | |
if start && finish | |
proc { |value| value >= start && value <= finish } | |
elsif start | |
proc { |value| value >= start } | |
elsif finish | |
proc { |value| value <= finish } | |
else | |
proc { |value| true } | |
end | |
end | |
end | |
class TimeFilterRanged | |
attr_reader :start, :finish, :range | |
def initialize(start, finish) | |
@start = start | |
@finish = finish | |
@range = Range.new(start, finish) | |
end | |
def to_proc | |
range = self.range | |
proc do |value| | |
range.include?(value) | |
end | |
end | |
end | |
SECONDS_IN_MINUTE = 60 | |
SECONDS_IN_HOUR = 60 * SECONDS_IN_MINUTE | |
SECONDS_IN_DAY = 24 * SECONDS_IN_HOUR | |
BASE_TIME = Time.new(1990, 1, 1) | |
# Gets up to 2017-05-18 01:00:00 -0500 | |
times = 10_000.times.map { |i| BASE_TIME + (i * SECONDS_IN_DAY) } | |
tf_original = TimeFilter.new( | |
Time.new(2000, 01, 01), nil | |
) | |
tf_local = TimeFilterLocal.new( | |
Time.new(2000, 01, 01), nil | |
) | |
tf_hoisted_local = TimeFilterHoistedLocal.new( | |
Time.new(2000, 01, 01), nil | |
) | |
tf_filtered_proc_branch = TimeFilterProcBranch.new( | |
Time.new(2000, 01, 01), nil | |
) | |
tf_filtered_range = TimeFilterRanged.new( | |
Time.new(2000, 01, 01), nil | |
) | |
Benchmark.ips do |bench| | |
bench.report("Original") { times.select(&tf_original) } | |
bench.report("Local") { times.select(&tf_local) } | |
bench.report("Hoisted Local") { times.select(&tf_hoisted_local) } | |
bench.report("Filtered Proc") { times.select(&tf_filtered_proc_branch) } | |
bench.report("Filtered Range") { times.select(&tf_filtered_range) } | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment