sorted_containers 0.0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -3
- data/CHANGELOG.md +5 -1
- data/README.md +133 -10
- data/lib/sorted_containers/sorted_array.rb +854 -0
- data/lib/sorted_containers/sorted_hash.rb +152 -0
- data/lib/sorted_containers/sorted_set.rb +82 -9
- data/lib/sorted_containers/version.rb +1 -1
- data/lib/sorted_containers.rb +2 -5
- metadata +9 -7
- data/lib/sorted_containers/sorted_list.rb +0 -174
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfda36be3b51c7acd9fc3083b948af1e18db3031949849ead8d6d4c7bb387411
|
4
|
+
data.tar.gz: 54463856fd55d0c10233a43fbbe7c1e4f6f38b28e621c805b02fe5d57d0719a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b5972feccf4fa6cd42e17f47cfbd2ba6d5b61350122428c0c4b26b70e2ca544dcb35e7eaea62aca1583fa1887da29b222239f16d0c139204cf2fafed77eb335
|
7
|
+
data.tar.gz: a67960920d793c0c968cfa0efa95b0806832d5d5684949cc9f20bac4d3595d269e00b27ac2d206b6522de1a6ba5a099a80029580a4b5933915b0e75dd99016bc
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,24 +1,147 @@
|
|
1
1
|
# SortedContainers
|
2
2
|
|
3
|
-
|
3
|
+
SortedContainers is a fast implementation of sorted lists, sets, and dictionaries in pure Ruby. It is based on the [sortedcontainers](https://grantjenks.com/docs/sortedcontainers/) Python library by Grant Jenks.
|
4
4
|
|
5
|
-
|
5
|
+
SortedContainers provides three main classes: `SortedArray`, `SortedSet`, and `SortedHash`. Each class is a drop-in replacement for the corresponding Ruby class, but with the added benefit of maintaining the elements in sorted order.
|
6
|
+
|
7
|
+
SortedContainers exploits the fact that modern computers are really good at shifting arrays in memory. We sacrifice theroetical time complexity for practical performance. In practice, SortedContainers is fast.
|
8
|
+
|
9
|
+
## How it works
|
10
|
+
|
11
|
+
Computers are good at shifting arrays. For that reason, it's often faster to keep an array sorted than to use the usual tree-based data structures.
|
12
|
+
|
13
|
+
For example, if you have the array `[1, 2, 4, 5]` and want to insert the element `3`, you can shift `4, 5` to the right and insert `3` in the correct position. This is a `O(n)` operation, but in practice it's fast.
|
14
|
+
|
15
|
+
But we can do better if we have a lot of elements. We can break up the array into smaller arrays so the shifts don't have to move so many elements. For example, if you have the array `[[1,2,4], [5,6,7]]` and you want to insert the element `3`, you can insert `3` into the first array to get `[[1,2,3,4], [5,6,7]]` and only the element `4` has to be shifted.
|
16
|
+
|
17
|
+
This often outperforms the more common tree-based data structures like red-black trees with `O(log n)` insertions and deletions. In practice, the `O(n)` insertions and deletions of SortedContainers are faster.
|
18
|
+
|
19
|
+
How big the subarrays are is a trade-off. You can modify how big you want to subarrays by setting the `load_factor`. The default is set to DEFAULT_LOAD_FACTOR = 1000. The subarray is split when its size is `2*load_factor`. There is no perfect value. The ideal value will depend on your use case and may require some experimentation.
|
20
|
+
|
21
|
+
## Benchmarks
|
22
|
+
|
23
|
+
Performance comparison against [SortedSet](https://github.com/knu/sorted_set) a C extension red-black tree implementation. Every test was run 5 times and the average was taken.
|
24
|
+
|
25
|
+
You can see that SortedContainers has compariable performance for add and delete, and much better performance for iteration, initialization, and include.
|
26
|
+
|
27
|
+
Note: I do not know why initialization is faster for 4 million than 3 million elements. This was consistant across multiple runs.
|
28
|
+
|
29
|
+
- MacBook Pro (16-inch, 2019)
|
30
|
+
- 2.6 GHz 6-Core Intel Core i7, 16 GB 2667 MHz DDR4
|
31
|
+
- Ruby 3.2.2
|
32
|
+
- SortedContainers 0.1.0
|
33
|
+
- SortedSet 1.0.3
|
34
|
+
|
35
|
+
### Results (Lower is better)
|
36
|
+
|
37
|
+
<img src="https://github.com/GarrisonJ/sorted_containers/blob/main/benchmark/initialize_performance_comparison.png?raw=true" width="50%">
|
38
|
+
|
39
|
+
<img src="https://github.com/GarrisonJ/sorted_containers/blob/main/benchmark/add_performance_comparison.png?raw=true" width="50%">
|
40
|
+
|
41
|
+
<img src="https://github.com/GarrisonJ/sorted_containers/blob/main/benchmark/delete_performance_comparison.png?raw=true" width="50%">
|
42
|
+
|
43
|
+
<img src="https://github.com/GarrisonJ/sorted_containers/blob/main/benchmark/iteration_performance_comparison.png?raw=true" width="50%">
|
44
|
+
|
45
|
+
<img src="https://github.com/GarrisonJ/sorted_containers/blob/main/benchmark/include_performance_comparison.png?raw=true" width="50%">
|
6
46
|
|
7
47
|
## Installation
|
8
48
|
|
9
|
-
|
49
|
+
Add this line to your application's Gemfile:
|
10
50
|
|
11
|
-
|
51
|
+
```ruby
|
52
|
+
gem 'sorted_containers'
|
53
|
+
```
|
12
54
|
|
13
|
-
|
55
|
+
And then execute:
|
14
56
|
|
15
|
-
|
57
|
+
```bash
|
58
|
+
bundle install
|
59
|
+
```
|
16
60
|
|
17
|
-
|
61
|
+
Or install it yourself as:
|
62
|
+
|
63
|
+
```bash
|
64
|
+
gem install sorted_containers
|
65
|
+
```
|
18
66
|
|
19
67
|
## Usage
|
20
68
|
|
21
|
-
|
69
|
+
require 'sorted_containers'
|
70
|
+
|
71
|
+
# Create a new SortedArray
|
72
|
+
list = SortedContainers::SortedArray.new
|
73
|
+
|
74
|
+
# Add elements to the list
|
75
|
+
list << 3
|
76
|
+
list << 1
|
77
|
+
list << 2
|
78
|
+
|
79
|
+
# Access elements by index
|
80
|
+
puts list[0] # => 1
|
81
|
+
puts list[1] # => 2
|
82
|
+
puts list[2] # => 3
|
83
|
+
|
84
|
+
# Access elements by index
|
85
|
+
puts list.first # => 1
|
86
|
+
puts list.last # => 3
|
87
|
+
|
88
|
+
# Remove elements from the list
|
89
|
+
list.delete(2)
|
90
|
+
|
91
|
+
# Iterate over the list
|
92
|
+
list.each do |element|
|
93
|
+
puts element
|
94
|
+
end
|
95
|
+
|
96
|
+
# Create a new SortedSet
|
97
|
+
set = SortedContainers::SortedSet.new
|
98
|
+
|
99
|
+
# Add elements to the set
|
100
|
+
set << 3
|
101
|
+
set << 1
|
102
|
+
set << 2
|
103
|
+
|
104
|
+
# Access elements by index
|
105
|
+
puts set[0] # => 1
|
106
|
+
puts set[1] # => 2
|
107
|
+
puts set[2] # => 3
|
108
|
+
|
109
|
+
# Access elements by index
|
110
|
+
puts set.first # => 1
|
111
|
+
puts set.last # => 3
|
112
|
+
|
113
|
+
# Remove elements from the set
|
114
|
+
set.delete(2)
|
115
|
+
|
116
|
+
# Iterate over the set
|
117
|
+
set.each do |element|
|
118
|
+
puts element
|
119
|
+
end
|
120
|
+
|
121
|
+
# Create a new SortedHash
|
122
|
+
dict = SortedContainers::SortedHash.new
|
123
|
+
|
124
|
+
# Add elements to the dict
|
125
|
+
dict[3] = 'three'
|
126
|
+
dict[1] = 'one'
|
127
|
+
dict[2] = 'two'
|
128
|
+
|
129
|
+
# Access elements by key
|
130
|
+
puts dict[1] # => 'one'
|
131
|
+
puts dict[2] # => 'two'
|
132
|
+
puts dict[3] # => 'three'
|
133
|
+
|
134
|
+
# Access elements by index
|
135
|
+
puts dict.first # => [1, 'one']
|
136
|
+
puts dict.last # => [3, 'three']
|
137
|
+
|
138
|
+
# Remove elements from the dict
|
139
|
+
dict.delete(2)
|
140
|
+
|
141
|
+
# Iterate over the dict
|
142
|
+
dict.each do |key, value|
|
143
|
+
puts "#{key}: #{value}"
|
144
|
+
end
|
22
145
|
|
23
146
|
## Development
|
24
147
|
|
@@ -28,7 +151,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
28
151
|
|
29
152
|
## Contributing
|
30
153
|
|
31
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
154
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/GarrisonJ/sorted_containers. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/GarrisonJ/sorted_containers/blob/main/CODE_OF_CONDUCT.md).
|
32
155
|
|
33
156
|
## License
|
34
157
|
|
@@ -36,4 +159,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
36
159
|
|
37
160
|
## Code of Conduct
|
38
161
|
|
39
|
-
Everyone interacting in the SortedContainers project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/
|
162
|
+
Everyone interacting in the SortedContainers project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/GarrisonJ/sorted_containers/blob/main/CODE_OF_CONDUCT.md).
|