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 abinoam commented Jun 15, 2015

Could you add the

self == self.uniq

approach?

@danielpclark

This comment has been minimized.

Copy link
Owner Author

@danielpclark danielpclark commented Jun 15, 2015

Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment