min_max 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 48b9b64396908ffd54a712e8a8e9b4eb6546e0538a6c168a69d67304dc6fcf1d
4
- data.tar.gz: 487b79da6a3a3f99ab408af1feb17ebe33c21c08b7c64b9e20e5b259bcf764bf
3
+ metadata.gz: 6d739946dcb0939e2e05893222c927f4dea0eda65da5c0a00156402de3e49c29
4
+ data.tar.gz: 61b4453a94b93bb2ccefd0787a751cef5d3ef380ac0ed591c73c3b0afddc394b
5
5
  SHA512:
6
- metadata.gz: '086026e3dfe0851390e4090e700aed60a27eaaf70ae53beb9a50164fd78a024797513994b2bd3c67995b29a655c6c8ca755b19ff42797e12190fae9bac10f4c6'
7
- data.tar.gz: b7cebaf1da79607d638628c1ef2d54ff11126902e9c1072d4c2bfd1db883db662d323c9e760134c76941747f447494141122e2a4dad6dd0ddc9a65682bfcfd9f
6
+ metadata.gz: 70dd4402ca82a60cffbc451ea134ca9fc34391f28311d23726d22055bfc01db9ba62002f0d54c76282888993613f2bf5618dcfa7a964da39c6995747401f3a3f
7
+ data.tar.gz: 31ada4f8ed50624701e389c6a1d50b83b75a585ef703d2f18c6511498dc9373647fa1f88d959ccdcbf56336d38dc550e1ce96710644f65970f2341549f843d53
data/Cargo.lock CHANGED
@@ -270,9 +270,9 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
270
270
 
271
271
  [[package]]
272
272
  name = "shlex"
273
- version = "1.1.0"
273
+ version = "1.3.0"
274
274
  source = "registry+https://github.com/rust-lang/crates.io-index"
275
- checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
275
+ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
276
276
 
277
277
  [[package]]
278
278
  name = "syn"
data/Cargo.toml CHANGED
@@ -8,5 +8,6 @@ resolver = "2"
8
8
 
9
9
  [profile.release]
10
10
  opt-level = 3
11
- lto = "fat"
11
+ lto = "thin"
12
12
  codegen-units = 1
13
+ strip = "debuginfo"
data/README.md CHANGED
@@ -24,10 +24,6 @@ Add this line to your application's Gemfile:
24
24
 
25
25
  ```ruby
26
26
  gem 'min_max'
27
-
28
- # or manually specify target . E.g.
29
-
30
- CARGO_BUILD_TARGET=x86_64-apple-darwin gem install min_max
31
27
  ```
32
28
 
33
29
 
@@ -40,6 +36,10 @@ bundle install
40
36
  Or install it yourself as:
41
37
  ```bash
42
38
  gem install min_max
39
+
40
+ # or manually specify target . E.g.
41
+
42
+ CARGO_BUILD_TARGET=x86_64-apple-darwin gem install min_max
43
43
  ```
44
44
 
45
45
  ## Usage
@@ -0,0 +1,85 @@
1
+ require "bundler/setup"
2
+ require "min_max"
3
+
4
+ require 'bundler/inline'
5
+
6
+ gemfile do
7
+ source 'https://rubygems.org'
8
+ gem 'rb_heap'
9
+ gem 'algorithms'
10
+ gem 'ruby-heap'
11
+ gem 'pqueue'
12
+ end
13
+
14
+ require 'benchmark'
15
+ require 'rb_heap'
16
+ require 'min_max'
17
+
18
+
19
+ data = 100_000.times.map{ Random.rand(0...1000_000_000) }
20
+ rb_hp = Heap.new(:<)
21
+ mm_hp = MinMax[]
22
+
23
+ Benchmark.bm do |x|
24
+ x.report("push_rb_heap"){ data.each{|d| rb_hp.add(d) } }
25
+ x.report("push_mm_heap"){ data.each{|d| mm_hp.push(d) } }
26
+ x.report("push_mm_heap_batches"){ mm_hp = MinMax[]; data.each_slice(1000){|d| mm_hp.push(*d) } }
27
+ end
28
+
29
+ Benchmark.bm do |x|
30
+ x.report("pop_rb_heap"){ 100_000.times{|d| rb_hp.pop } }
31
+ x.report("pop_mm_heap"){ 100_000.times{|d| mm_hp.pop_min } }
32
+ x.report("pop_mm_heap_batches"){ 1000.times{|d| mm_hp.pop_min(100) } }
33
+ end
34
+
35
+ Object.send(:remove_const, :Heap)
36
+
37
+ require 'Heap'
38
+ puts "# ruby-heap vs min_max"
39
+ ruby_hp = Heap::BinaryHeap::MinHeap.new
40
+ mm_hp = MinMax[]
41
+
42
+ Benchmark.bm do |x|
43
+ x.report("push_ruby_heap"){ data.each{|d| ruby_hp.add(d) } }
44
+ x.report("push_mm_heap"){ data.each{|d| mm_hp.push(d) } }
45
+ x.report("push_mm_heap_batches"){ mm_hp = MinMax[]; data.each_slice(1000){|d| mm_hp.push(*d) } }
46
+ end
47
+
48
+ Benchmark.bm do |x|
49
+ x.report("pop_ruby_heap"){ 100_000.times{|d| ruby_hp.extract_min! } }
50
+ x.report("pop_mm_heap"){ 100_000.times{|d| mm_hp.pop_min } }
51
+ x.report("pop_mm_heap_batches"){ 1000.times{|d| mm_hp.pop_min(100) } }
52
+ end
53
+
54
+
55
+ require 'algorithms'
56
+ minheap = Containers::MinHeap.new()
57
+ mm_hp = MinMax[]
58
+
59
+ Benchmark.bm do |x|
60
+ x.report("push_algos_heap"){ data.each{|d| minheap.push(d) } }
61
+ x.report("push_mm_heap"){ data.each{|d| mm_hp.push(d) } }
62
+ x.report("push_mm_heap_batches"){ mm_hp = MinMax[]; data.each_slice(1000){|d| mm_hp.push(*d) } }
63
+ end
64
+
65
+ Benchmark.bm do |x|
66
+ x.report("pop_algos_heap"){ 100_000.times{|d| minheap.pop } }
67
+ x.report("pop_mm_heap"){ 100_000.times{|d| mm_hp.pop_min } }
68
+ x.report("pop_mm_heap_batches"){ 1000.times{|d| mm_hp.pop_min(100) } }
69
+ end
70
+
71
+ require 'pqueue'
72
+ pqueue = PQueue.new()
73
+ mm_hp = MinMax[]
74
+
75
+ Benchmark.bm do |x|
76
+ x.report("push_algos_heap"){ data.each{|d| pqueue.push(d) } }
77
+ x.report("push_mm_heap"){ data.each{|d| mm_hp.push(d) } }
78
+ x.report("push_mm_heap_batches"){ mm_hp = MinMax[]; data.each_slice(1000){|d| mm_hp.push(*d) } }
79
+ end
80
+
81
+ Benchmark.bm do |x|
82
+ x.report("pop_algos_heap"){ 100_000.times{|d| minheap.pop } }
83
+ x.report("pop_mm_heap"){ 100_000.times{|d| mm_hp.pop_min } }
84
+ x.report("pop_mm_heap_batches"){ 1000.times{|d| mm_hp.pop_min(100) } }
85
+ end
@@ -52,9 +52,9 @@ impl RubyMinMaxHeap {
52
52
 
53
53
  fn push(&self, values: RArray) -> Result<(), Error> {
54
54
  let mut hp = self.heap.borrow_mut();
55
- let values_vec = values.to_vec::<(i64, i64)>().unwrap();
56
- values_vec.into_iter().for_each(|(priority, key)| {
57
- hp.push(PriorityOrderableValue(priority, key));
55
+ let values_vec = values.to_vec::<(i64, i64)>()?;
56
+ values_vec.iter().for_each(|(priority, key)| {
57
+ hp.push(PriorityOrderableValue(*priority, *key));
58
58
  });
59
59
  Ok(())
60
60
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class MinMax
4
- VERSION = "0.1.4"
4
+ VERSION = "0.1.5"
5
5
  end
data/lib/min_max.rb CHANGED
@@ -6,7 +6,7 @@ require_relative "min_max/min_max"
6
6
  class MinMax
7
7
  class Error < StandardError; end
8
8
 
9
- attr_reader :priority_blk, :storage, :counts, :mtx
9
+ attr_reader :priority_blk, :storage, :mtx
10
10
 
11
11
  def self.[](*args, &blk)
12
12
  new(*args, &blk)
@@ -15,9 +15,8 @@ class MinMax
15
15
  def self.new(*args, &blk)
16
16
  self._new.tap{|s|
17
17
  s.instance_eval{
18
- @priority_blk = (blk || proc{|x| (x.respond_to?(:priority) ? x.priority : x.to_i ) rescue 0})
19
- @storage = Hash.new
20
- @counts = Hash.new(0)
18
+ @priority_blk = (blk || proc{|x| x.respond_to?(:priority) ? x.priority : x.to_i })
19
+ @storage = Hash.new{|h,k| h[k] = [0, nil] }
21
20
  @mtx ||= Mutex.new
22
21
  }
23
22
  s.push(*args)
@@ -25,18 +24,17 @@ class MinMax
25
24
  end
26
25
 
27
26
  def push(*args)
28
- mtx.synchronize do
29
- mapped = args.map do |a|
30
- self.counts[a.hash] += 1
31
- self.storage[a.hash] = a
32
- [
33
- self.priority_blk.call(a),
34
- a.hash
35
- ]
36
- end
37
- _push(mapped)
27
+ mapped = args.map do |a|
28
+ hash = a.hash
29
+ entry = self.storage[hash]
30
+ entry[0] += 1
31
+ entry[1] ||= a
32
+ [
33
+ (self.priority_blk.call(a) rescue 0),
34
+ hash
35
+ ]
38
36
  end
39
- self
37
+ _push(mapped)
40
38
  end
41
39
 
42
40
  def add(*args)
@@ -44,17 +42,13 @@ class MinMax
44
42
  end
45
43
 
46
44
  def pop_max(*args)
47
- mtx.synchronize {
48
- popped = _pop_max(*args)
49
- popped.kind_of?(Array) ? popped.map{|p| retrieve(p) } : retrieve(popped)
50
- }
45
+ popped = _pop_max(*args)
46
+ popped.kind_of?(Array) ? popped.map{|p| retrieve(p) } : retrieve(popped)
51
47
  end
52
48
 
53
49
  def pop_min(*args)
54
- mtx.synchronize {
55
- popped = _pop_min(*args)
56
- popped.kind_of?(Array) ? popped.map{|p| retrieve(p) } : retrieve(popped)
57
- }
50
+ popped = _pop_min(*args)
51
+ popped.kind_of?(Array) ? popped.map{|p| retrieve(p) } : retrieve(popped)
58
52
  end
59
53
 
60
54
  def peek_min(*args)
@@ -101,15 +95,9 @@ class MinMax
101
95
 
102
96
  private
103
97
  def retrieve(hash, remove=true)
104
- if remove
105
- if (self.counts[hash] -= 1) == 0
106
- self.storage.delete(hash)
107
- else
108
- self.storage[hash]
109
- end
110
- else
111
- self.storage[hash]
112
- end
98
+ entry = self.storage[hash]
99
+ self.storage.delete(hash) if remove && (entry[0] -= 1) == 0
100
+ entry[1]
113
101
  end
114
102
 
115
103
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: min_max
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wouter Coppieters
@@ -66,6 +66,7 @@ files:
66
66
  - LICENSE.txt
67
67
  - README.md
68
68
  - Rakefile
69
+ - benchmarks/benchmarks.rb
69
70
  - ext/min_max/Cargo.toml
70
71
  - ext/min_max/extconf.rb
71
72
  - ext/min_max/src/lib.rs