Skip to content

Commit fc202c5

Browse files
committed
Use Rc instead of Box for interned strings.
We currently heap-allocate each one twice, once for Interner::names and once for Interner::strings. Using Rc instead means each one is allocated once and then shared. This speeds up numerous rustc-perf runs, the best by 4%.
1 parent f9bfe84 commit fc202c5

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

src/libsyntax_pos/symbol.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use serialize::{Decodable, Decoder, Encodable, Encoder};
2020
use std::fmt;
2121
use std::cmp::{PartialEq, Ordering, PartialOrd, Ord};
2222
use std::hash::{Hash, Hasher};
23+
use std::rc::Rc;
2324

2425
#[derive(Copy, Clone, Eq)]
2526
pub struct Ident {
@@ -200,11 +201,16 @@ impl<T: ::std::ops::Deref<Target=str>> PartialEq<T> for Symbol {
200201

201202
#[derive(Default)]
202203
pub struct Interner {
203-
names: FxHashMap<Box<str>, Symbol>,
204-
strings: Vec<Box<str>>,
204+
names: FxHashMap<Rc<str>, Symbol>,
205+
strings: Vec<Rc<str>>,
205206
gensyms: Vec<Symbol>,
206207
}
207208

209+
// The impl is safe because the ref counts are only modified by one thread at a
210+
// time, during insertion and during destruction. These may happen on different
211+
// threads, but are mutually excluded.
212+
unsafe impl Send for Interner {}
213+
208214
impl Interner {
209215
pub fn new() -> Self {
210216
Interner::default()
@@ -224,7 +230,7 @@ impl Interner {
224230
}
225231

226232
let name = Symbol(self.strings.len() as u32);
227-
let string = string.to_string().into_boxed_str();
233+
let string: Rc<str> = Rc::from(string);
228234
self.strings.push(string.clone());
229235
self.names.insert(string, name);
230236
name

0 commit comments

Comments
 (0)