Skip to content

Commit b5e8a3a

Browse files
committed
Auto merge of rust-lang#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 88189a7 + 93b0a1a commit b5e8a3a

File tree

1 file changed

+26
-22
lines changed

1 file changed

+26
-22
lines changed

compiler/rustc_infer/src/infer/freshen.rs

+26-22
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ pub struct TypeFreshener<'a, 'tcx> {
4141
infcx: &'a InferCtxt<'tcx>,
4242
ty_freshen_count: u32,
4343
const_freshen_count: u32,
44-
ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>,
45-
const_freshen_map: FxHashMap<ty::InferConst, ty::Const<'tcx>>,
44+
ty_freshen_key_vec: Vec<ty::InferTy>,
45+
ty_freshen_value_vec: Vec<Ty<'tcx>>,
46+
const_freshen_key_vec: Vec<ty::InferConst>,
47+
const_freshen_value_vec: Vec<ty::Const<'tcx>>,
4648
}
4749

4850
impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
@@ -51,8 +53,10 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
5153
infcx,
5254
ty_freshen_count: 0,
5355
const_freshen_count: 0,
54-
ty_freshen_map: Default::default(),
55-
const_freshen_map: Default::default(),
56+
ty_freshen_key_vec: Vec::new(),
57+
ty_freshen_value_vec: Vec::new(),
58+
const_freshen_key_vec: Vec::new(),
59+
const_freshen_value_vec: Vec::new(),
5660
}
5761
}
5862

@@ -64,15 +68,15 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
6468
return ty.fold_with(self);
6569
}
6670

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-
}
71+
if let Some(idx) = self.ty_freshen_key_vec.iter().position(|infty| *infty == key) {
72+
unsafe { self.ty_freshen_value_vec[idx] }
73+
} else {
74+
let index = self.ty_freshen_count;
75+
self.ty_freshen_count += 1;
76+
let t = mk_fresh(index);
77+
self.ty_freshen_key_vec.push(key);
78+
self.ty_freshen_value_vec.push(t);
79+
t
7680
}
7781
}
7882

@@ -90,15 +94,15 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
9094
return ct.fold_with(self);
9195
}
9296

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-
}
97+
if let Some(idx) = self.const_freshen_key_vec.iter().position(|infty| *infty == key) {
98+
unsafe { self.const_freshen_value_vec[idx] }
99+
} else {
100+
let index: u32 = self.const_freshen_count;
101+
self.const_freshen_count += 1;
102+
let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index), ty);
103+
self.const_freshen_key_vec.push(key);
104+
self.const_freshen_value_vec.push(ct);
105+
ct
102106
}
103107
}
104108
}

0 commit comments

Comments
 (0)