d_heap 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,8 +8,34 @@ require "mkmf"
8
8
  # $CFLAGS << " -g -ginline-points "
9
9
  # $CFLAGS << " -fno-omit-frame-pointer "
10
10
 
11
- if enable_config("debug")
12
- CONFIG["warnflags"] << " -Werror -Wpedantic "
11
+ # Use `rake compile -- --enable-debug`
12
+ debug_mode = enable_config("debug", ENV["EXTCONF_DEBUG"] == "1")
13
+
14
+ # Use `rake compile -- --enable-development`
15
+ devel_mode = enable_config("development") || debug_mode
16
+
17
+ if debug_mode
18
+ $stderr.puts "Building in debug mode." # rubocop:disable Style/StderrPuts
19
+ CONFIG["warnflags"] \
20
+ << " -ggdb" \
21
+ << " -DDEBUG"
22
+ end
23
+
24
+ if devel_mode
25
+ $stderr.puts "Building in development mode." # rubocop:disable Style/StderrPuts
26
+ CONFIG["warnflags"] \
27
+ << " -Wall " \
28
+ << " -Wpedantic" \
29
+ # There are warnings on MacOS that are annoying to debug (I don't have a Mac).
30
+ unless RbConfig::CONFIG["target_os"] =~ /darwin/
31
+ CONFIG["warnflags"] << " -Werror"
32
+ end
33
+ end
34
+
35
+ # Use `rake compile -- --enable-heapmap`
36
+ if enable_config("heapmap", true)
37
+ $stderr.puts "Building with DHeap::Map support." # rubocop:disable Style/StderrPuts
38
+ $defs.push "-DDHEAP_MAP"
13
39
  end
14
40
 
15
41
  have_func "rb_gc_mark_movable" # since ruby-2.7
@@ -17,6 +43,11 @@ have_func "rb_gc_mark_movable" # since ruby-2.7
17
43
  check_sizeof("long")
18
44
  check_sizeof("unsigned long long")
19
45
  check_sizeof("long double")
20
- have_macro("LDBL_MANT_DIG", "float.h")
46
+ check_sizeof("double")
47
+
48
+ unless have_macro("LDBL_MANT_DIG", "float.h")
49
+ raise NotImplementedError, "Missing LDBL_MANT_DIG."
50
+ end
21
51
 
52
+ create_header
22
53
  create_makefile("d_heap/d_heap")
data/images/push_n.png CHANGED
Binary file
Binary file
data/images/push_pop.png CHANGED
Binary file
data/lib/d_heap.rb CHANGED
@@ -83,7 +83,7 @@ class DHeap
83
83
  # If all pushes are popped, the default is probably best.
84
84
  # @param capacity [Integer] initial capacity of the heap.
85
85
  def initialize(d: DEFAULT_D, capacity: DEFAULT_CAPA) # rubocop:disable Naming/MethodParameterName
86
- __init_without_kw__(d, capacity)
86
+ __init_without_kw__(d, capacity, false)
87
87
  end
88
88
 
89
89
  # Consumes the heap by popping each minumum value until it is empty.
@@ -108,4 +108,28 @@ class DHeap
108
108
  nil
109
109
  end
110
110
 
111
+ if defined?(Map)
112
+
113
+ # Unlike {DHeap}, an object can only be added into a {DHeap::Map} once. Any
114
+ # subsequent addition simply rescores the already existing member. Objects
115
+ # are identified by their {#hash} value, just like with Hash.
116
+ class Map
117
+ alias score :[]
118
+ alias rescore :[]=
119
+ alias update :[]=
120
+
121
+ # Initialize a _d_-ary min-heap which can map objects to scores.
122
+ #
123
+ # @param d [Integer] Number of children for each parent node.
124
+ # Higher values generally speed up push but slow down pop.
125
+ # If all pushes are popped, the default is probably best.
126
+ # @param capacity [Integer] initial capacity of the heap.
127
+ def initialize(d: DEFAULT_D, capacity: DEFAULT_CAPA) # rubocop:disable Naming/MethodParameterName
128
+ __init_without_kw__(d, capacity, true)
129
+ end
130
+
131
+ end
132
+
133
+ end
134
+
111
135
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class DHeap
4
- VERSION = "0.6.1"
4
+ VERSION = "0.7.0"
5
5
 
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: d_heap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nicholas a. evans
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-24 00:00:00.000000000 Z
11
+ date: 2021-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark_driver
@@ -48,53 +48,29 @@ extensions:
48
48
  - ext/d_heap/extconf.rb
49
49
  extra_rdoc_files: []
50
50
  files:
51
+ - ".clang-format"
51
52
  - ".github/workflows/main.yml"
52
53
  - ".gitignore"
53
- - ".rspec"
54
54
  - ".rubocop.yml"
55
- - ".travis.yml"
56
55
  - ".yardopts"
57
56
  - CHANGELOG.md
58
57
  - CODE_OF_CONDUCT.md
59
- - Gemfile
60
- - Gemfile.lock
58
+ - D
61
59
  - LICENSE.txt
62
- - N
63
60
  - README.md
64
- - Rakefile
65
- - benchmarks/perf.rb
66
- - benchmarks/push_n.yml
67
- - benchmarks/push_n_pop_n.yml
68
- - benchmarks/push_pop.yml
69
- - benchmarks/stackprof.rb
70
- - bin/bench_charts
71
- - bin/bench_n
72
- - bin/benchmark-driver
73
- - bin/benchmarks
74
- - bin/console
75
- - bin/profile
76
- - bin/rake
77
- - bin/rspec
78
- - bin/rubocop
79
- - bin/setup
80
61
  - d_heap.gemspec
81
62
  - docs/benchmarks-2.txt
82
63
  - docs/benchmarks-mem.txt
83
64
  - docs/benchmarks.txt
84
65
  - docs/profile.txt
66
+ - ext/d_heap/.rubocop.yml
85
67
  - ext/d_heap/d_heap.c
86
68
  - ext/d_heap/extconf.rb
87
69
  - images/push_n.png
88
70
  - images/push_n_pop_n.png
89
71
  - images/push_pop.png
90
72
  - images/wikipedia-min-heap.png
91
- - lib/benchmark_driver/runner/ips_zero_fail.rb
92
73
  - lib/d_heap.rb
93
- - lib/d_heap/benchmarks.rb
94
- - lib/d_heap/benchmarks/benchmarker.rb
95
- - lib/d_heap/benchmarks/implementations.rb
96
- - lib/d_heap/benchmarks/profiler.rb
97
- - lib/d_heap/benchmarks/rspec_matchers.rb
98
74
  - lib/d_heap/version.rb
99
75
  homepage: https://github.com/nevans/d_heap
100
76
  licenses:
@@ -121,5 +97,5 @@ requirements: []
121
97
  rubygems_version: 3.1.4
122
98
  signing_key:
123
99
  specification_version: 4
124
- summary: A d-ary heap implementation, for priority queues
100
+ summary: very fast min-heap priority queue
125
101
  test_files: []
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/.travis.yml DELETED
@@ -1,6 +0,0 @@
1
- ---
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.7.2
6
- before_install: gem install bundler -v 2.1.4
data/Gemfile DELETED
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source "https://rubygems.org"
4
-
5
- # Specify your gem's dependencies in d_heap.gemspec
6
- gemspec
7
-
8
- gem "pry"
9
- gem "rake", "~> 13.0"
10
- gem "rake-compiler"
11
- gem "rspec", "~> 3.10"
12
- gem "rubocop", "~> 1.0"
13
-
14
- install_if -> { RUBY_PLATFORM !~ /darwin/ } do
15
- gem "benchmark_driver-output-gruff"
16
- end
17
-
18
- gem "perf"
19
- gem "priority_queue_cxx"
20
- gem "stackprof"
data/Gemfile.lock DELETED
@@ -1,83 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- d_heap (0.6.1)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- ast (2.4.1)
10
- benchmark_driver (0.15.16)
11
- benchmark_driver-output-gruff (0.3.1)
12
- benchmark_driver (>= 0.12.0)
13
- gruff
14
- coderay (1.1.3)
15
- diff-lcs (1.4.4)
16
- gruff (0.12.1)
17
- histogram
18
- rmagick
19
- histogram (0.2.4.1)
20
- method_source (1.0.0)
21
- parallel (1.19.2)
22
- parser (2.7.2.0)
23
- ast (~> 2.4.1)
24
- perf (0.1.2)
25
- priority_queue_cxx (0.3.4)
26
- pry (0.13.1)
27
- coderay (~> 1.1)
28
- method_source (~> 1.0)
29
- rainbow (3.0.0)
30
- rake (13.0.3)
31
- rake-compiler (1.1.1)
32
- rake
33
- regexp_parser (1.8.2)
34
- rexml (3.2.3)
35
- rmagick (4.1.2)
36
- rspec (3.10.0)
37
- rspec-core (~> 3.10.0)
38
- rspec-expectations (~> 3.10.0)
39
- rspec-mocks (~> 3.10.0)
40
- rspec-core (3.10.0)
41
- rspec-support (~> 3.10.0)
42
- rspec-expectations (3.10.0)
43
- diff-lcs (>= 1.2.0, < 2.0)
44
- rspec-support (~> 3.10.0)
45
- rspec-mocks (3.10.0)
46
- diff-lcs (>= 1.2.0, < 2.0)
47
- rspec-support (~> 3.10.0)
48
- rspec-support (3.10.0)
49
- rubocop (1.2.0)
50
- parallel (~> 1.10)
51
- parser (>= 2.7.1.5)
52
- rainbow (>= 2.2.2, < 4.0)
53
- regexp_parser (>= 1.8)
54
- rexml
55
- rubocop-ast (>= 1.0.1)
56
- ruby-progressbar (~> 1.7)
57
- unicode-display_width (>= 1.4.0, < 2.0)
58
- rubocop-ast (1.1.1)
59
- parser (>= 2.7.1.5)
60
- ruby-prof (1.4.2)
61
- ruby-progressbar (1.10.1)
62
- stackprof (0.2.16)
63
- unicode-display_width (1.7.0)
64
-
65
- PLATFORMS
66
- ruby
67
-
68
- DEPENDENCIES
69
- benchmark_driver
70
- benchmark_driver-output-gruff
71
- d_heap!
72
- perf
73
- priority_queue_cxx
74
- pry
75
- rake (~> 13.0)
76
- rake-compiler
77
- rspec (~> 3.10)
78
- rubocop (~> 1.0)
79
- ruby-prof
80
- stackprof
81
-
82
- BUNDLED WITH
83
- 2.2.3
data/Rakefile DELETED
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- require "rubocop/rake_task"
9
-
10
- RuboCop::RakeTask.new
11
-
12
- require "rake/extensiontask"
13
-
14
- task build: :compile
15
-
16
- Rake::ExtensionTask.new("d_heap") do |ext|
17
- ext.lib_dir = "lib/d_heap"
18
- end
19
-
20
- task default: %i[clobber compile spec rubocop]
data/benchmarks/perf.rb DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "perf"
5
-
6
- system("#{RbConfig.ruby} bin/rake compile", err: :out, exception: true)
7
- require "d_heap/benchmarks"
8
- include DHeap::Benchmarks # rubocop:disable Style/MixinUsage
9
- fill_random_vals
10
-
11
- n = ENV.fetch("BENCH_N", 5_000_000).to_i
12
- # interval = ENV.fetch("PROF_INTERVAL", 100).to_i # measured in μs
13
-
14
- i = 0
15
-
16
- q = initq RbHeap
17
- n.times { q << n }
18
- q.clear
19
-
20
- Perf.record do
21
- while i < n
22
- q << random_val
23
- i += 1
24
- end
25
- while 0 < i # rubocop:disable Style/NumericPredicate
26
- q.pop
27
- i -= 1
28
- end
29
- end
@@ -1,35 +0,0 @@
1
- ---
2
- prelude: |
3
- system("#{RbConfig.ruby} bin/rake compile", err: :out, exception: true)
4
- require "d_heap/benchmarks"
5
- include DHeap::Benchmarks
6
- fill_random_vals
7
-
8
- N = ENV.fetch("BENCH_N", 1000).to_i
9
-
10
- benchmark:
11
- - script: &script |
12
- if __bmdv_i % N == 0
13
- q.clear
14
- end
15
-
16
- q << random_val
17
- name: "push N (findmin)"
18
- prelude: "q = initq FindMin"
19
- loop_count: 24000000
20
- - script: *script
21
- name: "push N (bsearch)"
22
- prelude: "q = initq BSearch"
23
- loop_count: 2300000
24
- - script: *script
25
- name: "push N (rb_heap)"
26
- prelude: "q = initq RbHeap"
27
- loop_count: 9800000
28
- - script: *script
29
- name: "push N (c++ stl)"
30
- prelude: "q = initq CppSTL"
31
- loop_count: 18700000
32
- - script: *script
33
- name: "push N (c_dheap)"
34
- prelude: "q = initq DHeap"
35
- loop_count: 25100000
@@ -1,52 +0,0 @@
1
- ---
2
- prelude: |
3
- system("#{RbConfig.ruby} bin/rake compile", err: :out, exception: true)
4
- require "d_heap/benchmarks"
5
- include DHeap::Benchmarks
6
- fill_random_vals
7
-
8
- N = ENV.fetch("BENCH_N", 1000).to_i
9
- N2 = N * 2
10
-
11
- i = j = 0
12
-
13
- benchmark:
14
- - script: &script |
15
- if i < N
16
- q.clear if __bmdv_i == 0
17
- q << random_val
18
- i += 1
19
-
20
- elsif j < N
21
- q.pop
22
- j += 1
23
-
24
- elsif q.empty?
25
- i = 1
26
- j = 0
27
- q.clear
28
- q << random_val
29
-
30
- else
31
- raise "q not empty!"
32
- end
33
-
34
- name: "push N + pop N (findmin)"
35
- prelude: "q = initq FindMin"
36
- loop_count: 200000
37
- - script: *script
38
- name: "push N + pop N (bsearch)"
39
- prelude: "q = initq BSearch"
40
- loop_count: 4000000
41
- - script: *script
42
- name: "push N + pop N (rb_heap)"
43
- prelude: "q = initq RbHeap"
44
- loop_count: 4000000
45
- - script: *script
46
- name: "push N + pop N (c++ stl)"
47
- prelude: "q = initq CppSTL"
48
- loop_count: 16000000
49
- - script: *script
50
- name: "push N + pop N (c_dheap)"
51
- prelude: "q = initq DHeap"
52
- loop_count: 16000000