Skip to content

Commit 616633f

Browse files
committed
Compare string search performance of phf::Map and FxHashMap
1 parent 351843f commit 616633f

File tree

4 files changed

+23
-7
lines changed

4 files changed

+23
-7
lines changed

compiler/rustc_span/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#![feature(nll)]
2323
#![feature(min_specialization)]
2424
#![feature(option_expect_none)]
25+
#![feature(zzz)]
2526

2627
#[macro_use]
2728
extern crate rustc_macros;

compiler/rustc_span/src/symbol.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// ignore-tidy-filelength
2+
13
//! An "interner" is a data structure that associates values with usize tags and
24
//! allows bidirectional lookup; i.e., given a value, one can easily find the
35
//! type, and vice versa.
@@ -5056,7 +5058,7 @@ impl Symbol {
50565058

50575059
/// Maps a string to its interned representation.
50585060
pub fn intern(string: &str) -> Self {
5059-
if let Some(symbol) = STATIC_SYMBOLS_PHF.get(string) {
5061+
if let Some(symbol) = unsafe { STATIC_SYMBOLS.get(string) } {
50605062
*symbol
50615063
} else {
50625064
with_interner(|interner| interner.intern(string))
@@ -5141,13 +5143,23 @@ pub struct Interner {
51415143
strings: Vec<&'static str>,
51425144
}
51435145

5146+
use std::hash::BuildHasherDefault;
5147+
use std::marker::PhantomData;
5148+
5149+
#[allow(unused)]
5150+
static mut STATIC_SYMBOLS: FxHashMap<&'static str, Symbol> =
5151+
FxHashMap::with_hasher(BuildHasherDefault(PhantomData));
5152+
51445153
impl Interner {
51455154
fn prefill(init: &[&'static str]) -> Self {
5146-
Interner {
5147-
strings: init.into(),
5148-
names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
5149-
..Default::default()
5155+
let names: FxHashMap<_, _> = init.iter().copied().zip((0..).map(Symbol::new)).collect();
5156+
unsafe {
5157+
STATIC_SYMBOLS = names.clone();
5158+
// Some memory fence must go here,
5159+
// and all accesses to `Symbol::intern` must go after it.
51505160
}
5161+
5162+
Interner { strings: init.into(), names, ..Default::default() }
51515163
}
51525164

51535165
#[inline]

library/core/src/hash/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,9 @@ pub trait BuildHasher {
496496
/// [`HashSet`]: ../../std/collections/struct.HashSet.html
497497
/// [zero-sized]: https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts
498498
#[stable(since = "1.7.0", feature = "build_hasher")]
499-
pub struct BuildHasherDefault<H>(marker::PhantomData<H>);
499+
pub struct BuildHasherDefault<H>(
500+
#[stable(since = "1.7.0", feature = "build_hasher")] pub marker::PhantomData<H>,
501+
);
500502

501503
#[stable(since = "1.9.0", feature = "core_impl_debug")]
502504
impl<H> fmt::Debug for BuildHasherDefault<H> {

library/std/src/collections/hash/map.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,8 @@ impl<K, V, S> HashMap<K, V, S> {
263263
/// ```
264264
#[inline]
265265
#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
266-
pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
266+
#[rustc_const_unstable(feature = "zzz", issue = "123456")]
267+
pub const fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
267268
HashMap { base: base::HashMap::with_hasher(hash_builder) }
268269
}
269270

0 commit comments

Comments
 (0)