Skip to content

Commit 67af906

Browse files
committed
Auto merge of #120151 - Nilstrieb:hashmap-testing, r=<try>
[PERF EXPERIMENTS] Hashmap experiment I've been thinking about some sort of more efficient way of dealing with small hashmaps, since the vast majority of hashmaps are small.. (non-empty maps only) ``` 0.5..= 1: 0 (0.0%) 1..= 2: 15 (0.0061269%) 2..= 4: 176617 (72.14%) 4..= 8: 203093 (82.955%) 8..= 16: 232412 (94.93%) 16..= 32: 240221 (98.12%) 32..= 64: 243007 (99.258%) 64..= 128: 244165 (99.731%) 128..= 256: 244512 (99.873%) 256..= 512: 244692 (99.946%) 512..= 1024: 244734 (99.963%) 1024..= 2048: 244763 (99.975%) 2048..= 4096: 244780 (99.982%) 4096..= 8192: 244795 (99.988%) 8192..= 16384: 244808 (99.993%) 16384..= 32768: 244816 (99.997%) ``` let's try something with the most popular small map r? `@ghost`
2 parents 5378c1c + f8cb67c commit 67af906

File tree

1 file changed

+26
-24
lines changed

1 file changed

+26
-24
lines changed

compiler/rustc_infer/src/infer/freshen.rs

+26-24
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,18 @@
3131
//! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type
3232
//! inferencer knows "so far".
3333
use super::InferCtxt;
34-
use rustc_data_structures::fx::FxHashMap;
3534
use rustc_middle::infer::unify_key::ToType;
3635
use rustc_middle::ty::fold::TypeFolder;
3736
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt};
38-
use std::collections::hash_map::Entry;
3937

4038
pub struct TypeFreshener<'a, 'tcx> {
4139
infcx: &'a InferCtxt<'tcx>,
4240
ty_freshen_count: u32,
4341
const_freshen_count: u32,
44-
ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>,
45-
const_freshen_map: FxHashMap<ty::InferConst, ty::Const<'tcx>>,
42+
ty_freshen_key_vec: Vec<ty::InferTy>,
43+
ty_freshen_value_vec: Vec<Ty<'tcx>>,
44+
const_freshen_key_vec: Vec<ty::InferConst>,
45+
const_freshen_value_vec: Vec<ty::Const<'tcx>>,
4646
}
4747

4848
impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
@@ -51,8 +51,10 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
5151
infcx,
5252
ty_freshen_count: 0,
5353
const_freshen_count: 0,
54-
ty_freshen_map: Default::default(),
55-
const_freshen_map: Default::default(),
54+
ty_freshen_key_vec: Vec::new(),
55+
ty_freshen_value_vec: Vec::new(),
56+
const_freshen_key_vec: Vec::new(),
57+
const_freshen_value_vec: Vec::new(),
5658
}
5759
}
5860

@@ -64,15 +66,15 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
6466
return ty.fold_with(self);
6567
}
6668

67-
match self.ty_freshen_map.entry(key) {
68-
Entry::Occupied(entry) => *entry.get(),
69-
Entry::Vacant(entry) => {
70-
let index = self.ty_freshen_count;
71-
self.ty_freshen_count += 1;
72-
let t = mk_fresh(index);
73-
entry.insert(t);
74-
t
75-
}
69+
if let Some(idx) = self.ty_freshen_key_vec.iter().position(|infty| *infty == key) {
70+
unsafe { *self.ty_freshen_value_vec.get_unchecked(idx) }
71+
} else {
72+
let index = self.ty_freshen_count;
73+
self.ty_freshen_count += 1;
74+
let t = mk_fresh(index);
75+
self.ty_freshen_key_vec.push(key);
76+
self.ty_freshen_value_vec.push(t);
77+
t
7678
}
7779
}
7880

@@ -90,15 +92,15 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
9092
return ct.fold_with(self);
9193
}
9294

93-
match self.const_freshen_map.entry(key) {
94-
Entry::Occupied(entry) => *entry.get(),
95-
Entry::Vacant(entry) => {
96-
let index = self.const_freshen_count;
97-
self.const_freshen_count += 1;
98-
let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index), ty);
99-
entry.insert(ct);
100-
ct
101-
}
95+
if let Some(idx) = self.const_freshen_key_vec.iter().position(|infty| *infty == key) {
96+
unsafe { *self.const_freshen_value_vec.get_unchecked(idx) }
97+
} else {
98+
let index: u32 = self.const_freshen_count;
99+
self.const_freshen_count += 1;
100+
let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index), ty);
101+
self.const_freshen_key_vec.push(key);
102+
self.const_freshen_value_vec.push(ct);
103+
ct
102104
}
103105
}
104106
}

0 commit comments

Comments
 (0)