From f6ba8decf3ed346758329d130d4a796f3a4cb81a Mon Sep 17 00:00:00 2001 From: Gabriel Teles Date: Sun, 14 May 2017 12:40:30 -0300 Subject: [PATCH 1/2] comparing array subset checks --- README.md | 20 ++++++++++++++++ ...us-empty-vs-interception-vs-include-all.rb | 23 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 code/array/minus-empty-vs-interception-vs-include-all.rb diff --git a/README.md b/README.md index 81f1b44..afe27b4 100644 --- a/README.md +++ b/README.md @@ -389,6 +389,26 @@ Comparison: Array#insert: 0.2 i/s - 262.56x slower ``` +##### Subset detection with `Array#-#empty?` vs `Array#&#==` vs `Array#all?#include?` [code](minus-empty-vs-interception-vs-include-all.rb) + +``` +$ ruby -v code/array/minus-empty-vs-interception-vs-include-all.rb +ruby 2.1.5p273 (2014-11-13) [x86_64-linux-gnu] +Warming up -------------------------------------- + (a1 - a2).empty? 5.116k i/100ms + (a1 & a2) == a1 4.387k i/100ms + Array#all?#include? 8.673k i/100ms +Calculating ------------------------------------- + (a1 - a2).empty? 52.210k (± 3.8%) i/s - 260.916k in 5.005454s + (a1 & a2) == a1 43.958k (± 4.5%) i/s - 219.350k in 5.001017s + Array#all?#include? 90.781k (± 2.4%) i/s - 459.669k in 5.066504s + +Comparison: + Array#all?#include?: 90781.0 i/s + (a1 - a2).empty?: 52210.4 i/s - 1.74x slower + (a1 & a2) == a1 : 43958.3 i/s - 2.07x slower +``` + ### Enumerable ##### `Enumerable#each + push` vs `Enumerable#map` [code](code/enumerable/each-push-vs-map.rb) diff --git a/code/array/minus-empty-vs-interception-vs-include-all.rb b/code/array/minus-empty-vs-interception-vs-include-all.rb new file mode 100644 index 0000000..9b4f90f --- /dev/null +++ b/code/array/minus-empty-vs-interception-vs-include-all.rb @@ -0,0 +1,23 @@ +require 'benchmark/ips' + +ARRAY1 = [*1..25] +ARRAY2 = [*1..100] + +def slow_minus_empty + (ARRAY1 - ARRAY2).empty? +end + +def slow_interception + (ARRAY1 & ARRAY2) == ARRAY1 +end + +def fast + ARRAY1.all?{|element| ARRAY2.include?(element) } +end + +Benchmark.ips do |x| + x.report("(a1 - a2).empty?") { slow_minus_empty } + x.report("(a1 & a2) == a1 ") { slow_interception } + x.report("Array#all?#include?") { fast } + x.compare! +end From 910385085b6f681de640a0fa57b35fa277ce6c33 Mon Sep 17 00:00:00 2001 From: Gabriel Teles Date: Wed, 31 May 2017 09:27:56 -0300 Subject: [PATCH 2/2] more subset checking methods --- README.md | 30 +++++++++++-------- ...n-vs-include-all.rb => subset-checking.rb} | 17 +++++++++-- 2 files changed, 32 insertions(+), 15 deletions(-) rename code/array/{minus-empty-vs-interception-vs-include-all.rb => subset-checking.rb} (56%) diff --git a/README.md b/README.md index afe27b4..d6710f7 100644 --- a/README.md +++ b/README.md @@ -389,24 +389,30 @@ Comparison: Array#insert: 0.2 i/s - 262.56x slower ``` -##### Subset detection with `Array#-#empty?` vs `Array#&#==` vs `Array#all?#include?` [code](minus-empty-vs-interception-vs-include-all.rb) +##### Subset detection with various methods [code](code/array/subset-checking.rb) ``` -$ ruby -v code/array/minus-empty-vs-interception-vs-include-all.rb -ruby 2.1.5p273 (2014-11-13) [x86_64-linux-gnu] +$ ruby -v code/array/subset-checking.rb +ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux] Warming up -------------------------------------- - (a1 - a2).empty? 5.116k i/100ms - (a1 & a2) == a1 4.387k i/100ms - Array#all?#include? 8.673k i/100ms + (a1 - a2).empty? 19.534k i/100ms + (a1 & a2) == a1 16.190k i/100ms + Array#all?#include? 27.391k i/100ms + Array#&#size 16.949k i/100ms + Set#subset? 4.289k i/100ms Calculating ------------------------------------- - (a1 - a2).empty? 52.210k (± 3.8%) i/s - 260.916k in 5.005454s - (a1 & a2) == a1 43.958k (± 4.5%) i/s - 219.350k in 5.001017s - Array#all?#include? 90.781k (± 2.4%) i/s - 459.669k in 5.066504s + (a1 - a2).empty? 206.885k (± 2.0%) i/s - 1.035M in 5.006270s + (a1 & a2) == a1 169.425k (± 2.4%) i/s - 858.070k in 5.067497s + Array#all?#include? 291.863k (± 2.1%) i/s - 1.479M in 5.070021s + Array#&#size 176.342k (± 2.9%) i/s - 898.297k in 5.098513s + Set#subset? 43.342k (± 3.0%) i/s - 218.739k in 5.051749s Comparison: - Array#all?#include?: 90781.0 i/s - (a1 - a2).empty?: 52210.4 i/s - 1.74x slower - (a1 & a2) == a1 : 43958.3 i/s - 2.07x slower + Array#all?#include?: 291862.7 i/s + (a1 - a2).empty?: 206885.5 i/s - 1.41x slower + Array#&#size: 176341.9 i/s - 1.66x slower + (a1 & a2) == a1: 169424.9 i/s - 1.72x slower + Set#subset?: 43341.6 i/s - 6.73x slower ``` ### Enumerable diff --git a/code/array/minus-empty-vs-interception-vs-include-all.rb b/code/array/subset-checking.rb similarity index 56% rename from code/array/minus-empty-vs-interception-vs-include-all.rb rename to code/array/subset-checking.rb index 9b4f90f..3123fbb 100644 --- a/code/array/minus-empty-vs-interception-vs-include-all.rb +++ b/code/array/subset-checking.rb @@ -1,23 +1,34 @@ require 'benchmark/ips' +require 'set' ARRAY1 = [*1..25] ARRAY2 = [*1..100] -def slow_minus_empty - (ARRAY1 - ARRAY2).empty? +def slow_set + ARRAY2.to_set.subset?(ARRAY1.to_set) end def slow_interception (ARRAY1 & ARRAY2) == ARRAY1 end +def slow_interception_size + (ARRAY1 & ARRAY2).size == ARRAY1.size +end + +def slow_minus_empty + (ARRAY1 - ARRAY2).empty? +end + def fast ARRAY1.all?{|element| ARRAY2.include?(element) } end Benchmark.ips do |x| x.report("(a1 - a2).empty?") { slow_minus_empty } - x.report("(a1 & a2) == a1 ") { slow_interception } + x.report("(a1 & a2) == a1") { slow_interception } x.report("Array#all?#include?") { fast } + x.report("Array#&#size") { slow_interception_size } + x.report("Set#subset?") { slow_set } x.compare! end