Last active
August 29, 2015 14:23
-
-
Save danielpclark/d27e3db346428a117712 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 'securerandom' | |
require 'benchmark' | |
# written to allow 65,536 unique array items | |
array_of_x = lambda {|x| SecureRandom.hex(x*2).scan(/..../) } | |
module Refinements | |
module BooleanUniqWithDupUniqBang | |
refine Array do | |
def uniq? | |
!self.dup.uniq! | |
end | |
end | |
end | |
module BooleanUniqWithEqualLength | |
refine Array do | |
def uniq? | |
self.length == self.uniq.length | |
end | |
end | |
end | |
module BooleanUniqWithEqualSort | |
refine Array do | |
def uniq? | |
self.sort == self.uniq.sort | |
end | |
end | |
end | |
module BooleanUniqWithEachIndex | |
refine Array do | |
def uniq? | |
self.each_with_index { |a,b| | |
self.each_with_index { |c,d| | |
next if b == d | |
return false if a == c | |
} | |
} | |
true | |
end | |
end | |
end | |
module BooleanUniqWithCombination | |
refine Array do | |
def uniq? | |
self.combination(2).each {|a,b| return false if a == b} | |
true | |
end | |
end | |
end | |
module BooleanUniqWithUniq | |
refine Array do | |
def uniq? | |
self == self.uniq | |
end | |
end | |
end | |
end | |
bench_reps = 10_000 | |
bench = Benchmark.benchmark("\nTesting various ways of implementing :uniq? on Array\n(smaller numbers are better)\n\n",34) do |x| | |
# Note doing anymore than one test per test type seems to wash the results into all things being equal. | |
# Only the first test gives realistic numbers. | |
[500].each do |qty| | |
x.report("Array.new(#{qty}) !self.dup.uniq!") { | |
using Refinements::BooleanUniqWithDupUniqBang | |
bench_reps.times do | |
array_of_x.(qty).uniq? | |
end | |
} | |
x.report("Array.new(#{qty}) == uniq.length") { | |
using Refinements::BooleanUniqWithEqualLength | |
bench_reps.times do | |
array_of_x.(qty).uniq? | |
end | |
} | |
x.report("Array.new(#{qty}) == uniq.sort") { | |
using Refinements::BooleanUniqWithEqualSort | |
bench_reps.times do | |
array_of_x.(qty).uniq? | |
end | |
} | |
x.report("Array.new(#{qty}) each index") { | |
using Refinements::BooleanUniqWithEachIndex | |
bench_reps.times do | |
array_of_x.(qty).uniq? | |
end | |
} | |
x.report("Array.new(#{qty}) combination(2)") { | |
using Refinements::BooleanUniqWithCombination | |
bench_reps.times do | |
array_of_x.(qty).uniq? | |
end | |
} | |
x.report("Array.new(#{qty}) == self.uniq") { | |
using Refinements::BooleanUniqWithUniq | |
bench_reps.times do | |
array_of_x.(qty).uniq? | |
end | |
} | |
end | |
end | |
require "minitest/autorun" | |
class A | |
using Refinements::BooleanUniqWithDupUniqBang | |
def a(arr) arr.uniq? end | |
end | |
class B | |
using Refinements::BooleanUniqWithEqualLength | |
def b(arr) arr.uniq? end | |
end | |
class C | |
using Refinements::BooleanUniqWithEqualSort | |
def c(arr) arr.uniq? end | |
end | |
class D | |
using Refinements::BooleanUniqWithEachIndex | |
def d(arr) arr.uniq? end | |
end | |
class E | |
using Refinements::BooleanUniqWithCombination | |
def e(arr) arr.uniq? end | |
end | |
class F | |
using Refinements::BooleanUniqWithUniq | |
def f(arr) arr.uniq? end | |
end | |
describe "Check validity of methods by comparing results" do | |
it "will return the same results" do | |
100.times do | |
arr = array_of_x.(10_000) | |
expect( | |
[A.new.a(arr), B.new.b(arr), C.new.c(arr), D.new.d(arr), E.new.e(arr), F.new.f(arr)].uniq.length | |
).must_equal 1 | |
end | |
end | |
end | |
# OUTPUT | |
# | |
# | |
# Testing various ways of implementing :uniq? on Array | |
# (smaller numbers are better) | |
# user system total real | |
# Array.new(500) !self.dup.uniq! 4.590000 0.010000 4.600000 ( 4.601021) | |
# Array.new(500) == uniq.length 4.640000 0.010000 4.650000 ( 4.662084) | |
# Array.new(500) == uniq.sort 6.650000 0.020000 6.670000 ( 6.674487) | |
# Array.new(500) each index 108.820000 0.280000 109.100000 (109.234954) | |
# Array.new(500) combination(2) 84.360000 0.220000 84.580000 ( 84.689277) | |
# Array.new(500) == self.uniq 4.790000 0.010000 4.800000 ( 4.805891) | |
# Run options: --seed 41152 | |
# | |
# # Running: | |
# | |
# . | |
# | |
# Finished in 3.895934s, 0.2567 runs/s, 25.6678 assertions/s. | |
# | |
# 1 runs, 100 assertions, 0 failures, 0 errors, 0 skips |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Could you add the
approach?