Skip to content

Commit 132995a

Browse files
committed
Auto merge of #207 - tkaitchuck:specialize, r=Amanieu
Enable specialization with aHash This uses the specialization feature in nightly to improve performance for hashing some classes (u8, u16, u32, u64, u128, [u8], and String) For these classes it improves performance by 15% the test `insert_ahash` benchmarks.
2 parents e4d6beb + f1d3137 commit 132995a

File tree

4 files changed

+132
-97
lines changed

4 files changed

+132
-97
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ edition = "2018"
1313

1414
[dependencies]
1515
# For the default hasher
16-
ahash = { version = "0.4.4", optional = true, default-features = false }
16+
ahash = { version = "0.6.1", default-features = false, optional = true }
1717

1818
# For external trait impls
1919
rayon = { version = "1.0", optional = true }
@@ -25,7 +25,7 @@ compiler_builtins = { version = "0.1.2", optional = true }
2525
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
2626

2727
[dev-dependencies]
28-
lazy_static = "1.2"
28+
lazy_static = "1.4"
2929
rand = { version = "0.7.3", features = ["small_rng"] }
3030
rayon = "1.0"
3131
fnv = "1.0.7"

README.md

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ in environments without `std`, such as embedded systems and kernels.
2626
## Features
2727

2828
- Drop-in replacement for the standard library `HashMap` and `HashSet` types.
29-
- Uses `AHash` as the default hasher, which is much faster than SipHash.
29+
- Uses [AHash](https://github.com/tkaitchuck/aHash) as the default hasher, which is much faster than SipHash.
3030
- Around 2x faster than the previous standard library `HashMap`.
3131
- Lower memory usage: only 1 byte of overhead per entry instead of 8.
3232
- Compatible with `#[no_std]` (but requires a global allocator with the `alloc` crate).
@@ -37,47 +37,46 @@ in environments without `std`, such as embedded systems and kernels.
3737

3838
Compared to the previous implementation of `std::collections::HashMap` (Rust 1.35).
3939

40-
With the hashbrown default AHash hasher (not HashDoS-resistant):
41-
42-
```text
43-
name oldstdhash ns/iter hashbrown ns/iter diff ns/iter diff % speedup
44-
insert_ahash_highbits 20,846 7,397 -13,449 -64.52% x 2.82
45-
insert_ahash_random 20,515 7,796 -12,719 -62.00% x 2.63
46-
insert_ahash_serial 21,668 7,264 -14,404 -66.48% x 2.98
47-
insert_erase_ahash_highbits 29,570 17,498 -12,072 -40.83% x 1.69
48-
insert_erase_ahash_random 39,569 17,474 -22,095 -55.84% x 2.26
49-
insert_erase_ahash_serial 32,073 17,332 -14,741 -45.96% x 1.85
50-
iter_ahash_highbits 1,572 2,087 515 32.76% x 0.75
51-
iter_ahash_random 1,609 2,074 465 28.90% x 0.78
52-
iter_ahash_serial 2,293 2,120 -173 -7.54% x 1.08
53-
lookup_ahash_highbits 3,460 4,403 943 27.25% x 0.79
54-
lookup_ahash_random 6,377 3,911 -2,466 -38.67% x 1.63
55-
lookup_ahash_serial 3,629 3,586 -43 -1.18% x 1.01
56-
lookup_fail_ahash_highbits 5,286 3,411 -1,875 -35.47% x 1.55
57-
lookup_fail_ahash_random 12,365 4,171 -8,194 -66.27% x 2.96
58-
lookup_fail_ahash_serial 4,902 3,240 -1,662 -33.90% x 1.51
59-
```
60-
61-
With the libstd default SipHash hasher (HashDoS-resistant):
62-
63-
```text
64-
name oldstdhash ns/iter hashbrown ns/iter diff ns/iter diff % speedup
65-
insert_std_highbits 32,598 20,199 -12,399 -38.04% x 1.61
66-
insert_std_random 29,824 20,760 -9,064 -30.39% x 1.44
67-
insert_std_serial 33,151 17,256 -15,895 -47.95% x 1.92
68-
insert_erase_std_highbits 74,731 48,735 -25,996 -34.79% x 1.53
69-
insert_erase_std_random 73,828 47,649 -26,179 -35.46% x 1.55
70-
insert_erase_std_serial 73,864 40,147 -33,717 -45.65% x 1.84
71-
iter_std_highbits 1,518 2,264 746 49.14% x 0.67
72-
iter_std_random 1,502 2,414 912 60.72% x 0.62
73-
iter_std_serial 6,361 2,118 -4,243 -66.70% x 3.00
74-
lookup_std_highbits 21,705 16,962 -4,743 -21.85% x 1.28
75-
lookup_std_random 21,654 17,158 -4,496 -20.76% x 1.26
76-
lookup_std_serial 18,726 14,509 -4,217 -22.52% x 1.29
77-
lookup_fail_std_highbits 25,852 17,323 -8,529 -32.99% x 1.49
78-
lookup_fail_std_random 25,913 17,760 -8,153 -31.46% x 1.46
79-
lookup_fail_std_serial 22,648 14,839 -7,809 -34.48% x 1.53
80-
```
40+
With the hashbrown default AHash hasher:
41+
42+
| name | oldstdhash ns/iter | hashbrown ns/iter | diff ns/iter | diff % | speedup |
43+
|:------------------------|:-------------------:|------------------:|:------------:|---------:|---------|
44+
| insert_ahash_highbits | 18,865 | 8,020 | -10,845 | -57.49% | x 2.35 |
45+
| insert_ahash_random | 19,711 | 8,019 | -11,692 | -59.32% | x 2.46 |
46+
| insert_ahash_serial | 19,365 | 6,463 | -12,902 | -66.63% | x 3.00 |
47+
| insert_erase_ahash_highbits | 51,136 | 17,916 | -33,220 | -64.96% | x 2.85 |
48+
| insert_erase_ahash_random | 51,157 | 17,688 | -33,469 | -65.42% | x 2.89 |
49+
| insert_erase_ahash_serial | 45,479 | 14,895 | -30,584 | -67.25% | x 3.05 |
50+
| iter_ahash_highbits | 1,399 | 1,092 | -307 | -21.94% | x 1.28 |
51+
| iter_ahash_random | 1,586 | 1,059 | -527 | -33.23% | x 1.50 |
52+
| iter_ahash_serial | 3,168 | 1,079 | -2,089 | -65.94% | x 2.94 |
53+
| lookup_ahash_highbits | 32,351 | 4,792 | -27,559 | -85.19% | x 6.75 |
54+
| lookup_ahash_random | 17,419 | 4,817 | -12,602 | -72.35% | x 3.62 |
55+
| lookup_ahash_serial | 15,254 | 3,606 | -11,648 | -76.36% | x 4.23 |
56+
| lookup_fail_ahash_highbits | 21,187 | 4,369 | -16,818 | -79.38% | x 4.85 |
57+
| lookup_fail_ahash_random | 21,550 | 4,395 | -17,155 | -79.61% | x 4.90 |
58+
| lookup_fail_ahash_serial | 19,450 | 3,176 | -16,274 | -83.67% | x 6.12 |
59+
60+
61+
With the libstd default SipHash hasher:
62+
63+
|name | oldstdhash ns/iter | hashbrown ns/iter | diff ns/iter | diff % | speedup |
64+
|:------------------------|:-------------------:|------------------:|:------------:|---------:|---------|
65+
|insert_std_highbits |19,216 |16,885 | -2,331 | -12.13% | x 1.14 |
66+
|insert_std_random |19,179 |17,034 | -2,145 | -11.18% | x 1.13 |
67+
|insert_std_serial |19,462 |17,493 | -1,969 | -10.12% | x 1.11 |
68+
|insert_erase_std_highbits |50,825 |35,847 | -14,978 | -29.47% | x 1.42 |
69+
|insert_erase_std_random |51,448 |35,392 | -16,056 | -31.21% | x 1.45 |
70+
|insert_erase_std_serial |87,711 |38,091 | -49,620 | -56.57% | x 2.30 |
71+
|iter_std_highbits |1,378 |1,159 | -219 | -15.89% | x 1.19 |
72+
|iter_std_random |1,395 |1,132 | -263 | -18.85% | x 1.23 |
73+
|iter_std_serial |1,704 |1,105 | -599 | -35.15% | x 1.54 |
74+
|lookup_std_highbits |17,195 |13,642 | -3,553 | -20.66% | x 1.26 |
75+
|lookup_std_random |17,181 |13,773 | -3,408 | -19.84% | x 1.25 |
76+
|lookup_std_serial |15,483 |13,651 | -1,832 | -11.83% | x 1.13 |
77+
|lookup_fail_std_highbits |20,926 |13,474 | -7,452 | -35.61% | x 1.55 |
78+
|lookup_fail_std_random |21,766 |13,505 | -8,261 | -37.95% | x 1.61 |
79+
|lookup_fail_std_serial |19,336 |13,519 | -5,817 | -30.08% | x 1.43 |
8180

8281
## Usage
8382

@@ -96,19 +95,18 @@ use hashbrown::HashMap;
9695
let mut map = HashMap::new();
9796
map.insert(1, "one");
9897
```
99-
98+
## Flags
10099
This crate has the following Cargo features:
101100

102-
- `nightly`: Enables nightly-only features: `#[may_dangle]`.
101+
- `nightly`: Enables nightly-only features including: `#[may_dangle]`.
103102
- `serde`: Enables serde serialization support.
104103
- `rayon`: Enables rayon parallel iterator support.
105104
- `raw`: Enables access to the experimental and unsafe `RawTable` API.
106105
- `inline-more`: Adds inline hints to most functions, improving run-time performance at the cost
107106
of compilation time. (enabled by default)
108107
- `ahash`: Compiles with ahash as default hasher. (enabled by default)
109-
- `ahash-compile-time-rng`: Activates the `compile-time-rng` feature of ahash, to increase the
110-
DOS-resistance, but can result in issues for `no_std` builds. More details in
111-
[issue#124](https://github.com/rust-lang/hashbrown/issues/124). (enabled by default)
108+
- `ahash-compile-time-rng`: Activates the `compile-time-rng` feature of ahash. For targets with no random number generator
109+
this pre-generates seeds at compile time and embeds them as constants. See [aHash's documentation](https://github.com/tkaitchuck/aHash#flags) (disabled by default)
112110

113111
## License
114112

0 commit comments

Comments
 (0)