priority_queue_cxx 0.3.2 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +9 -8
- data/ext/fast_containers/fc_pq.cpp +33 -33
- data/ext/fast_containers/fc_pq.h +20 -21
- data/lib/fc.rb +3 -3
- metadata +8 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9ba1b848409a000b5cb7ee56d1ae562eb7192aa7d705365a6f3b7a56729fbc89
|
4
|
+
data.tar.gz: 7a42739b6d89de0bce7e989938cfa352f8a32152cf0a43e377e584b22914374c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a7e866717d1e8c178f671bdb268180ac618d67a6e9489d027d28575179eab562866a87681ca1b539e6eddca2ef136e4494e7da3e58226a922f25ecde0ab8543
|
7
|
+
data.tar.gz: 1623288217123aac3da66d238c9178b21ff5aaa14421390c59d901d80ec2d861246972895b0d372fc97e9336f3a4636e8fa3242809e25342b8e77a726a331051
|
data/README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# PriorityQueueCxx
|
2
2
|
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/priority_queue_cxx.png)](http://badge.fury.io/rb/priority_queue_cxx)
|
4
|
+
[![priority_queue_cxx API Documentation](https://www.omniref.com/ruby/gems/priority_queue_cxx.png)](https://www.omniref.com/ruby/gems/priority_queue_cxx)
|
4
5
|
|
5
|
-
FastContainers provides a fast implementatin of priority queues for ruby. Speed is achieved by exposing the c++ standard implementation through a light ruby wrapper. As a bigger project, the library may grow a number of containers that are not in the standard ruby library and are presently only available as pure ruby libraries, but presently the library includes a single class named PriorityQueue. More containers will be added as necessity arises. Contributors and feature requests are most welcome.
|
6
6
|
|
7
|
-
|
7
|
+
*PriorityQueueCxx* provides a fast implementation of priority queues for ruby. Speed is achieved by exposing the c++ standard implementation through a light ruby wrapper. As a bigger project, the library may grow to provide a number of containers that are not in the standard ruby library and are presently only available as pure ruby libraries. Presently, however, the library includes a single class named PriorityQueue. More containers will be added as necessity arises. Contributors and feature requests are most welcome.
|
8
|
+
|
9
|
+
The library exposes a module named ```FastContainers``` (to be required using ```require 'fc'```) which provides the PriorityQueue class.
|
8
10
|
|
9
11
|
## Installation
|
10
12
|
|
@@ -29,7 +31,7 @@ q.pop
|
|
29
31
|
|
30
32
|
As far as I know, only one other library (the PriorityQueue gem) provides priority queues implemented as a C extension. This implies that the fc::PriorityQueue is a *lot* faster than most current alternatives and, as shown below, it compares favorably with the mentioned C extension as well.
|
31
33
|
|
32
|
-
To get an idea about how fast it is, below
|
34
|
+
To get an idea about how fast it is, below I provide a comparison of the time needed to push and pop a large number of elements into a priority queue. Each experiment compares FastContainers with other priority queues implementations. Since timings varies greatly among different implementations, the number of push/pop performed is chosen so to make the experiments to run for (at most) few minutes.
|
33
35
|
|
34
36
|
The following table summarizes the outputs, detailed results can be found in the next few sections. All libraries have been installed through the 'gem' command and executed using ruby v. 2.1.0.
|
35
37
|
|
@@ -42,7 +44,7 @@ The following table summarizes the outputs, detailed results can be found in the
|
|
42
44
|
| algorithms | 2584.6 | 29.6 |1307.1 |
|
43
45
|
| priority_queue | 1.4 |19134.6 |9568.0 |
|
44
46
|
|
45
|
-
where: results are sorted according to "avg μs per op" (higher is better); μs stands for micro seconds; op stands for any operation (push or pop); the figures for priority_queue_cxx has been calculated with the results of experiments with PriorityQueue (the experiment with the highest number of operations).
|
47
|
+
where: results are sorted according to "avg μs per op" (higher in the list is better); μs stands for micro seconds; op stands for any operation (push or pop); the figures for priority_queue_cxx has been calculated with the results of experiments with PriorityQueue (the experiment with the highest number of operations).
|
46
48
|
|
47
49
|
|
48
50
|
### Comparison with [algorithms (0.6.1)](http://rubygems.org/gems/algorithms) (50,000 push/pop)
|
@@ -205,7 +207,7 @@ As it usually happens, the answer is: it depends. The evidence reported above sh
|
|
205
207
|
|
206
208
|
## API
|
207
209
|
|
208
|
-
Here it follows a transcription of the RDoc documentation for the library. I'm adding it here because I'
|
210
|
+
Here it follows a transcription of the RDoc documentation for the library. I'm adding it here because I'm having difficulties in instructing the 'gem' executable to generate the correct files on installation (everything works fine using rdoc from the command line though). Any suggestion about how to solve this problem is *very* welcome.
|
209
211
|
|
210
212
|
### FastContainers::PriorityQueue
|
211
213
|
|
@@ -217,7 +219,7 @@ Create a new priority queue and returns it. queue_kind specifies whether to buil
|
|
217
219
|
|
218
220
|
Example:
|
219
221
|
|
220
|
-
```ruby
|
222
|
+
```ruby
|
221
223
|
pq = FastContainers::PriorityQueue.new(:min)
|
222
224
|
```
|
223
225
|
|
@@ -291,4 +293,3 @@ The class Includes Enumerable, so that standard enumeration based methods (e.g.,
|
|
291
293
|
## Notes
|
292
294
|
|
293
295
|
<sup id="ref1">1</sup> It is worth mentioning that, due to how priority queue are implemented by the C++ standard library, this implementation can't efficiently support priority changes. In any case, to support this feature would require important changes in the current API.<a href="#which-is-the-best-priority-queue-implementation-for-ruby" title="back reference">↩</a>
|
294
|
-
|
@@ -22,9 +22,9 @@
|
|
22
22
|
#include <iostream>
|
23
23
|
|
24
24
|
namespace fc_pq {
|
25
|
-
|
25
|
+
|
26
26
|
typedef std::pair<void*,double> PQElem;
|
27
|
-
|
27
|
+
|
28
28
|
class PairsComparator
|
29
29
|
{
|
30
30
|
bool reverse;
|
@@ -36,54 +36,54 @@ namespace fc_pq {
|
|
36
36
|
else return (lhs.second<rhs.second);
|
37
37
|
}
|
38
38
|
};
|
39
|
-
|
39
|
+
|
40
40
|
// --------------------------------------
|
41
41
|
// PQueue
|
42
42
|
// --------------------------------------
|
43
|
-
|
43
|
+
|
44
44
|
typedef std::vector<PQElem> PQueueStorage;
|
45
45
|
typedef unsigned int PQueueStorageVersion;
|
46
|
-
|
47
|
-
typedef struct _PQueue {
|
46
|
+
|
47
|
+
typedef struct _PQueue {
|
48
48
|
PQueueStorage storage;
|
49
49
|
PairsComparator comparator;
|
50
50
|
PQueueStorageVersion version;
|
51
|
-
|
51
|
+
|
52
52
|
_PQueue(PQueueKind kind) : comparator(kind), version(0) { }
|
53
|
-
}* PQueue;
|
53
|
+
}* PQueue;
|
54
54
|
|
55
55
|
void destroy(PQueue q){
|
56
56
|
delete q;
|
57
57
|
}
|
58
|
-
|
58
|
+
|
59
59
|
PQueue create(PQueueKind kind) {
|
60
60
|
return new _PQueue(kind);
|
61
61
|
}
|
62
|
-
|
62
|
+
|
63
63
|
/* Getting the size of the container */
|
64
64
|
unsigned int size(PQueue q) {
|
65
65
|
return q->storage.size();
|
66
66
|
}
|
67
|
-
|
68
|
-
|
67
|
+
|
68
|
+
|
69
69
|
void push(PQueue q, void* value, double priority) {
|
70
70
|
q->version++;
|
71
71
|
q->storage.push_back(PQElem(value, priority));
|
72
72
|
push_heap(q->storage.begin(), q->storage.end(), q->comparator);
|
73
73
|
}
|
74
|
-
|
74
|
+
|
75
75
|
void* top(PQueue q) {
|
76
76
|
return q->storage.at(0).first;
|
77
77
|
}
|
78
|
-
|
78
|
+
|
79
79
|
double top_key(PQueue q) {
|
80
80
|
return q->storage.at(0).second;
|
81
81
|
}
|
82
|
-
|
82
|
+
|
83
83
|
double second_best_key(PQueue q) {
|
84
84
|
if(q->storage.size()==2)
|
85
85
|
return q->storage.at(1).second;
|
86
|
-
|
86
|
+
|
87
87
|
double key1 = q->storage.at(1).second;
|
88
88
|
double key2 = q->storage.at(2).second;
|
89
89
|
if( key1 > key2 ) {
|
@@ -92,67 +92,67 @@ namespace fc_pq {
|
|
92
92
|
return key2;
|
93
93
|
}
|
94
94
|
}
|
95
|
-
|
95
|
+
|
96
96
|
void pop(PQueue q) {
|
97
97
|
q->version++;
|
98
98
|
pop_heap(q->storage.begin(), q->storage.end(), q->comparator);
|
99
99
|
q->storage.pop_back();
|
100
100
|
}
|
101
|
-
|
101
|
+
|
102
102
|
bool empty(PQueue q) {
|
103
103
|
return q->storage.empty();
|
104
104
|
}
|
105
|
-
|
105
|
+
|
106
106
|
// --------------------------------------
|
107
107
|
// Iterator
|
108
108
|
// --------------------------------------
|
109
|
-
|
110
|
-
|
109
|
+
|
110
|
+
|
111
111
|
typedef struct _PQueueIterator {
|
112
112
|
PQueueStorage::const_iterator iterator;
|
113
113
|
PQueue pqueue;
|
114
114
|
PQueueStorage* storage;
|
115
115
|
PQueueStorageVersion version;
|
116
|
-
|
117
|
-
_PQueueIterator(PQueue q) : iterator(q->storage.begin()), pqueue(q), storage(&q->storage), version(q->version)
|
116
|
+
|
117
|
+
_PQueueIterator(PQueue q) : iterator(q->storage.begin()), pqueue(q), storage(&q->storage), version(q->version)
|
118
118
|
{ }
|
119
|
-
|
120
|
-
void checkVersion()
|
119
|
+
|
120
|
+
void checkVersion() {
|
121
121
|
if(version != pqueue->version) {
|
122
122
|
throw PQueueException("FastContainers::PriorityQueue - a change in the priority queue invalidated the current iterator.");
|
123
123
|
}
|
124
124
|
}
|
125
125
|
} PQueueImplIterator;
|
126
126
|
#define QIT(it) ((PQueueImplIterator*)(it))
|
127
|
-
|
127
|
+
|
128
128
|
/* Returns a new iterator object */
|
129
129
|
PQueueIterator iterator(PQueue q) {
|
130
130
|
PQueueImplIterator* it = new PQueueImplIterator(q);
|
131
131
|
return it;
|
132
132
|
}
|
133
|
-
|
133
|
+
|
134
134
|
void iterator_dispose(PQueueIterator it) {
|
135
135
|
delete it;
|
136
136
|
}
|
137
|
-
|
137
|
+
|
138
138
|
/* Returns the value of the current element */
|
139
139
|
void* iterator_get_value(PQueueIterator it) {
|
140
140
|
return it->iterator->first;
|
141
141
|
}
|
142
|
-
|
142
|
+
|
143
143
|
/* Returns the priority of the current element */
|
144
144
|
double iterator_get_key(PQueueIterator it) {
|
145
145
|
return it->iterator->second;
|
146
146
|
}
|
147
|
-
|
147
|
+
|
148
148
|
/* Moves on to the next element */
|
149
|
-
PQueueIterator iterator_next(PQueueIterator it)
|
149
|
+
PQueueIterator iterator_next(PQueueIterator it) {
|
150
150
|
it->checkVersion();
|
151
151
|
it->iterator++;
|
152
152
|
return it;
|
153
153
|
}
|
154
|
-
|
154
|
+
|
155
155
|
bool iterator_end(PQueueIterator it) {
|
156
156
|
return it->iterator == it->storage->end();
|
157
157
|
}
|
158
|
-
}
|
158
|
+
}
|
data/ext/fast_containers/fc_pq.h
CHANGED
@@ -22,64 +22,63 @@
|
|
22
22
|
#define FC_QUEUE_H_KTY6FH1S
|
23
23
|
|
24
24
|
#include <queue>
|
25
|
+
#include <stdexcept>
|
25
26
|
|
26
27
|
namespace fc_pq {
|
27
28
|
class PQueueException : public std::runtime_error {
|
28
29
|
public:
|
29
30
|
PQueueException(const char* msg) : std::runtime_error(msg) {}
|
30
31
|
};
|
31
|
-
|
32
|
+
|
32
33
|
typedef struct _PQueue* PQueue;
|
33
34
|
typedef struct _PQueueIterator* PQueueIterator;
|
34
35
|
typedef enum { MIN_QUEUE, MAX_QUEUE } PQueueKind;
|
35
|
-
|
36
|
+
|
36
37
|
/* Constructor. It defaults to construct a max queue. If true is passed
|
37
|
-
it construct a min queue.*/
|
38
|
+
it construct a min queue.*/
|
38
39
|
PQueue create(PQueueKind kind);
|
39
|
-
|
40
|
+
|
40
41
|
/* Destructor */
|
41
|
-
void destroy(PQueue q);
|
42
|
-
|
42
|
+
void destroy(PQueue q);
|
43
|
+
|
43
44
|
/* Getting the size of the container */
|
44
45
|
unsigned int size(PQueue q);
|
45
|
-
|
46
|
+
|
46
47
|
/* Adding elements */
|
47
48
|
void push(PQueue q, void* value, double priority);
|
48
|
-
|
49
|
+
|
49
50
|
/* Inspecting the queue top (for values) */
|
50
51
|
void* top(PQueue q);
|
51
|
-
|
52
|
+
|
52
53
|
/* Inspecting the queue top (for priorities) */
|
53
54
|
double top_key(PQueue q);
|
54
|
-
|
55
|
+
|
55
56
|
/* Returns the priority of the next best element */
|
56
57
|
double second_best_key(PQueue q);
|
57
|
-
|
58
|
+
|
58
59
|
/* Removing the queue top */
|
59
60
|
void pop(PQueue q);
|
60
|
-
|
61
|
+
|
61
62
|
/* Returns true if the queue is empty */
|
62
63
|
bool empty(PQueue q);
|
63
|
-
|
64
|
+
|
64
65
|
/* Returns a new iterator object */
|
65
66
|
PQueueIterator iterator(PQueue q);
|
66
|
-
|
67
|
+
|
67
68
|
/* Dispose the iterator */
|
68
69
|
void iterator_dispose(PQueueIterator it);
|
69
|
-
|
70
|
+
|
70
71
|
/* Returns the value of the current element */
|
71
72
|
void* iterator_get_value(PQueueIterator it);
|
72
|
-
|
73
|
+
|
73
74
|
/* Returns the priority of the current element */
|
74
75
|
double iterator_get_key(PQueueIterator it);
|
75
|
-
|
76
|
+
|
76
77
|
/* Moves on to the next element */
|
77
|
-
PQueueIterator iterator_next(PQueueIterator it)
|
78
|
-
|
78
|
+
PQueueIterator iterator_next(PQueueIterator it);
|
79
|
+
|
79
80
|
/* Return true if the iterator is already out of the container */
|
80
81
|
bool iterator_end(PQueueIterator it);
|
81
82
|
}
|
82
83
|
|
83
84
|
#endif /* end of include guard: FC_QUEUE_H_KTY6FH1S */
|
84
|
-
|
85
|
-
|
data/lib/fc.rb
CHANGED
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: priority_queue_cxx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roberto Esposito
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2014-03-25 00:00:00.000000000 Z
|
@@ -24,7 +24,8 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
description:
|
27
|
+
description: Fast priority queue implementation (c++ wrapper, see README.md for a
|
28
|
+
comparison with other libraries)
|
28
29
|
email:
|
29
30
|
- boborbt@gmail.com
|
30
31
|
executables: []
|
@@ -45,11 +46,11 @@ files:
|
|
45
46
|
- test/performance/test_fc_vs_pqueue.rb
|
46
47
|
- test/performance/test_fc_vs_priority_queue.rb
|
47
48
|
- test/test_fast_containers.rb
|
48
|
-
homepage: https://github.com/boborbt/
|
49
|
+
homepage: https://github.com/boborbt/priority_queue_cxx
|
49
50
|
licenses:
|
50
51
|
- MIT
|
51
52
|
metadata: {}
|
52
|
-
post_install_message:
|
53
|
+
post_install_message:
|
53
54
|
rdoc_options:
|
54
55
|
- "--main"
|
55
56
|
- README.md
|
@@ -66,10 +67,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
67
|
- !ruby/object:Gem::Version
|
67
68
|
version: '0'
|
68
69
|
requirements: []
|
69
|
-
|
70
|
-
|
71
|
-
signing_key:
|
70
|
+
rubygems_version: 3.3.11
|
71
|
+
signing_key:
|
72
72
|
specification_version: 4
|
73
73
|
summary: Fast (c++ wrapper) priority queue implementation for ruby.
|
74
74
|
test_files: []
|
75
|
-
has_rdoc:
|