Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
@abinoam

This comment has been minimized.

Copy link

abinoam commented Jun 15, 2015

Could you add the

self == self.uniq

approach?

@danielpclark

This comment has been minimized.

Copy link
Owner Author

danielpclark commented Jun 15, 2015

Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.