Skip to content

Commit 3568346

Browse files
committed
Remove fast_binary_search. rust-lang/rust#45333 merged its implementation to the standard library.
1 parent 89c8ce2 commit 3568346

File tree

4 files changed

+4
-164
lines changed

4 files changed

+4
-164
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
[package]
1616
name = "ordslice"
17-
version = "0.1.0"
17+
version = "0.2.0"
1818
authors = ["Alkis Evlogimenos <[email protected]>"]
1919
description = "Extensions for ordered slices"
2020
homepage = "https://github.com/alkis/ordslice-rs"

README.md

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,11 @@ extern crate ordslice;
2727
use ordslice::Ext;
2828
```
2929

30-
Now you can enjoy super fast `lower_bound`, `upper_bound`, `equal_range`, and
31-
`fast_binary_search`.
32-
33-
`fast_binary_search` is much faster than `binary_search`:
34-
35-
```diff,ignore
36-
name std ns/iter fast ns/iter diff ns/iter diff % speedup
37-
+l1::dups 31 10 -21 -67.74% x 3.10
38-
+l1::unique 35 10 -25 -71.43% x 3.50
39-
+l2::dups 54 19 -35 -64.81% x 2.84
40-
+l2::unique 59 19 -40 -67.80% x 3.11
41-
+l3::dups 131 81 -50 -38.17% x 1.62
42-
+l3::unique 135 80 -55 -40.74% x 1.69
43-
```
30+
Now you can enjoy super fast `lower_bound`, `upper_bound`, and `equal_range`.
4431

4532
### Why isn't this part of the standard library?
4633

4734
Worry not, work is on the way:
4835

49-
- [ ] Make `binary_search` as fast as `fast_binary_search`: https://github.com/rust-lang/rust/pull/45333
36+
- [X] Make `binary_search` as fast as ~~`fast_binary_search`~~: https://github.com/rust-lang/rust/pull/45333
5037
- [ ] Add `lower_bound`, `upper_bound`, `equal_range` to std: https://github.com/rust-lang/rfcs/issues/2184

benches/bench.rs

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -106,32 +106,6 @@ fn generate_inputs(cache: Cache, config: Config) -> (Vec<usize>, Vec<usize>) {
106106
(values, lookups)
107107
}
108108

109-
mod binary_search {
110-
use super::*;
111-
fn run(b: &mut Bencher, cache: Cache, config: Config) {
112-
let (values, lookups) = generate_inputs(cache, config);
113-
let mut iter = lookups.iter().cycle();
114-
b.iter(|| {
115-
values.binary_search(iter.next().unwrap()).is_ok()
116-
})
117-
}
118-
119-
for_each_cache!();
120-
}
121-
122-
mod fast_binary_search {
123-
use super::*;
124-
fn run(b: &mut Bencher, cache: Cache, config: Config) {
125-
let (values, lookups) = generate_inputs(cache, config);
126-
let mut iter = lookups.iter().cycle();
127-
b.iter(|| {
128-
values.fast_binary_search(iter.next().unwrap()).is_ok()
129-
})
130-
}
131-
132-
for_each_cache!();
133-
}
134-
135109
mod lower_bound {
136110
use super::*;
137111
fn run(b: &mut Bencher, cache: Cache, config: Config) {

src/lib.rs

Lines changed: 1 addition & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020
//! use ordslice::Ext;
2121
//!
2222
//! let b = [1, 3];
23-
//! // This is faster than stdlib's binary_search!
24-
//! assert_eq!(b.fast_binary_search(&2), Err(1));
25-
//! assert_eq!(b.fast_binary_search(&3), Ok(1));
2623
//!
2724
//! assert_eq!(b.lower_bound(&1), 0);
2825
//!
@@ -32,80 +29,14 @@
3229
//! ```
3330
//!
3431
//! [`slice`]: https://doc.rust-lang.org/stable/std/primitive.slice.html
35-
use std::cmp::Ordering::{self, Less, Equal, Greater};
32+
use std::cmp::Ordering::{self, Less, Greater};
3633

3734
/// Extends [`slice`] with fast operations on ordered slices.
3835
///
3936
/// [`slice`]: https://doc.rust-lang.org/stable/std/primitive.slice.html
4037
pub trait Ext {
4138
type Item;
4239

43-
/// Checks if `x` appears in the ordered slice.
44-
///
45-
/// Returns `Ok(i)` where `i` is the index of the matching element, `Err(i)`
46-
/// otherwise where `i` is the index where the element should be inserted to
47-
/// preserve the slice's ordering.
48-
///
49-
/// The slice MUST be ordered by the order defined by its elements.
50-
///
51-
/// Note: this is the same as [`binary_search`] but faster.
52-
///
53-
/// | name |std (ns) |fast (ns) |diff (ns) | diff (%) | speedup |
54-
/// | -----------|---------|----------|----------|----------|---------|
55-
/// | l1::dups | 31 | 10 | -21 | -67.74% | x 3.10 |
56-
/// | l1::unique | 35 | 10 | -25 | -71.43% | x 3.50 |
57-
/// | l2::dups | 54 | 19 | -35 | -64.81% | x 2.84 |
58-
/// | l2::unique | 58 | 19 | -39 | -67.24% | x 3.05 |
59-
/// | l3::dups | 136 | 82 | -54 | -39.71% | x 1.66 |
60-
/// | l3::unique | 139 | 84 | -55 | -39.57% | x 1.65 |
61-
///
62-
/// [`binary_search`]:
63-
/// https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search
64-
fn fast_binary_search(&self, x: &Self::Item) -> Result<usize, usize>
65-
where
66-
Self::Item: Ord;
67-
68-
/// Check if there is an element `e` in the ordered slice such that `f(e) ==
69-
/// Equal`.
70-
///
71-
/// The slice MUST be ordered by the order defined by the comparator
72-
/// function. The comparator function should take an element and return
73-
/// `Ordering` that is consistent with the ordering of the slice. Returns
74-
/// `Ok(i)` where `i` is the index of the matching element, `Err(i)`
75-
/// otherwise where `i` is the index where the element should be inserted to
76-
/// preserve the slice's ordering.
77-
///
78-
/// # Example:
79-
///
80-
/// ```
81-
/// # use ordslice::Ext;
82-
/// let b = [1, 2, 3, 6, 9, 9];
83-
/// assert_eq!(b.fast_binary_search(&3), b.fast_binary_search_by(|x| x.cmp(&3)));
84-
/// ```
85-
fn fast_binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
86-
where
87-
F: FnMut(&'a Self::Item) -> Ordering;
88-
89-
/// Check if there is an element `e` in the ordered slice such that `f(e) ==
90-
/// k`.
91-
///
92-
/// The slice MUST be ordered by the order defined by the keys of its
93-
/// elements. Returns `Ok(i)` where `i` is the index of the matching
94-
/// element, `Err(i)` otherwise where `i` is the index where the element
95-
/// should be inserted to preserve the slice's ordering.
96-
///
97-
/// # Example:
98-
///
99-
/// ```
100-
/// # use ordslice::Ext;
101-
/// let b = [1, 2, 3, 6, 9, 9];
102-
/// assert_eq!(b.fast_binary_search(&3), b.fast_binary_search_by_key(&6, |x| x * 2));
103-
/// ```
104-
fn fast_binary_search_by_key<'a, K, F>(&'a self, k: &K, f: F) -> Result<usize, usize>
105-
where
106-
F: FnMut(&'a Self::Item) -> K,
107-
K: Ord;
108-
10940
/// Returns the index `i` pointing to the first element in the ordered slice
11041
/// that is _not less_ than `x`.
11142
///
@@ -289,44 +220,6 @@ pub trait Ext {
289220
impl<T> Ext for [T] {
290221
type Item = T;
291222

292-
fn fast_binary_search(&self, x: &Self::Item) -> Result<usize, usize>
293-
where
294-
T: Ord,
295-
{
296-
self.fast_binary_search_by(|y| y.cmp(x))
297-
}
298-
fn fast_binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
299-
where
300-
F: FnMut(&'a Self::Item) -> Ordering,
301-
{
302-
let s = self;
303-
let mut size = s.len();
304-
if size == 0 {
305-
return Err(0);
306-
}
307-
let mut base = 0usize;
308-
while size > 1 {
309-
let half = size / 2;
310-
let mid = base + half;
311-
let cmp = f(unsafe { s.get_unchecked(mid) });
312-
base = if cmp == Greater { base } else { mid };
313-
size -= half;
314-
}
315-
let cmp = f(unsafe { s.get_unchecked(base) });
316-
if cmp == Equal {
317-
Ok(base)
318-
} else {
319-
Err(base + (cmp == Less) as usize)
320-
}
321-
}
322-
fn fast_binary_search_by_key<'a, K, F>(&'a self, k: &K, mut f: F) -> Result<usize, usize>
323-
where
324-
F: FnMut(&'a Self::Item) -> K,
325-
K: Ord,
326-
{
327-
self.fast_binary_search_by(|e| f(e).cmp(k))
328-
}
329-
330223
fn lower_bound(&self, x: &Self::Item) -> usize
331224
where
332225
T: Ord,
@@ -445,20 +338,6 @@ impl<T> Ext for [T] {
445338
mod tests {
446339
use super::Ext;
447340

448-
#[test]
449-
fn binary_search() {
450-
let b: [u32; 0] = [];
451-
assert_eq!(b.fast_binary_search(&0), Err(0));
452-
let b = [1, 3, 3, 5];
453-
assert_eq!(b.fast_binary_search(&0), Err(0));
454-
assert_eq!(b.fast_binary_search(&1), Ok(0));
455-
assert_eq!(b.fast_binary_search(&2), Err(1));
456-
assert_eq!(b.fast_binary_search(&3), Ok(2));
457-
assert_eq!(b.fast_binary_search(&4), Err(3));
458-
assert_eq!(b.fast_binary_search(&5), Ok(3));
459-
assert_eq!(b.fast_binary_search(&6), Err(4));
460-
}
461-
462341
#[test]
463342
fn lower_bound() {
464343
let b: [u32; 0] = [];

0 commit comments

Comments
 (0)