From 0465201f772bf74e57885cfa64817314ac8c743b Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 11 Apr 2023 10:54:56 +0000 Subject: [PATCH 1/2] Use `itertools::Either` instead of own `EitherIter` impl --- Cargo.lock | 1 + compiler/rustc_data_structures/Cargo.toml | 1 + .../src/sso/either_iter.rs | 73 ------------------- compiler/rustc_data_structures/src/sso/map.rs | 36 ++++----- compiler/rustc_data_structures/src/sso/mod.rs | 1 - 5 files changed, 20 insertions(+), 92 deletions(-) delete mode 100644 compiler/rustc_data_structures/src/sso/either_iter.rs diff --git a/Cargo.lock b/Cargo.lock index 6dd6fbe71b83d..5f89f5e4a57ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4575,6 +4575,7 @@ dependencies = [ "elsa", "ena", "indexmap", + "itertools", "jobserver", "libc", "measureme", diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 24b6b5cfb1f73..2102f09c56a03 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -33,6 +33,7 @@ tempfile = "3.2" thin-vec = "0.2.12" tracing = "0.1" elsa = "=1.7.1" +itertools = "0.10.1" [dependencies.parking_lot] version = "0.11" diff --git a/compiler/rustc_data_structures/src/sso/either_iter.rs b/compiler/rustc_data_structures/src/sso/either_iter.rs deleted file mode 100644 index bca6c0955b905..0000000000000 --- a/compiler/rustc_data_structures/src/sso/either_iter.rs +++ /dev/null @@ -1,73 +0,0 @@ -use std::fmt; -use std::iter::FusedIterator; - -/// Iterator which may contain instance of -/// one of two specific implementations. -/// -/// Note: For most methods providing custom -/// implementation may marginally -/// improve performance by avoiding -/// doing Left/Right match on every step -/// and doing it only once instead. -#[derive(Clone)] -pub enum EitherIter { - Left(L), - Right(R), -} - -impl Iterator for EitherIter -where - L: Iterator, - R: Iterator, -{ - type Item = L::Item; - - fn next(&mut self) -> Option { - match self { - EitherIter::Left(l) => l.next(), - EitherIter::Right(r) => r.next(), - } - } - - fn size_hint(&self) -> (usize, Option) { - match self { - EitherIter::Left(l) => l.size_hint(), - EitherIter::Right(r) => r.size_hint(), - } - } -} - -impl ExactSizeIterator for EitherIter -where - L: ExactSizeIterator, - R: ExactSizeIterator, - EitherIter: Iterator, -{ - fn len(&self) -> usize { - match self { - EitherIter::Left(l) => l.len(), - EitherIter::Right(r) => r.len(), - } - } -} - -impl FusedIterator for EitherIter -where - L: FusedIterator, - R: FusedIterator, - EitherIter: Iterator, -{ -} - -impl fmt::Debug for EitherIter -where - L: fmt::Debug, - R: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - EitherIter::Left(l) => l.fmt(f), - EitherIter::Right(r) => r.fmt(f), - } - } -} diff --git a/compiler/rustc_data_structures/src/sso/map.rs b/compiler/rustc_data_structures/src/sso/map.rs index 7cdac58197714..f9e2dfd16d5c3 100644 --- a/compiler/rustc_data_structures/src/sso/map.rs +++ b/compiler/rustc_data_structures/src/sso/map.rs @@ -1,6 +1,6 @@ -use super::either_iter::EitherIter; use crate::fx::FxHashMap; use arrayvec::ArrayVec; +use itertools::Either; use std::fmt; use std::hash::Hash; use std::ops::Index; @@ -138,8 +138,8 @@ impl SsoHashMap { /// The iterator element type is `&'a K`. pub fn keys(&self) -> impl Iterator { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.iter().map(|(k, _v)| k)), - SsoHashMap::Map(map) => EitherIter::Right(map.keys()), + SsoHashMap::Array(array) => Either::Left(array.iter().map(|(k, _v)| k)), + SsoHashMap::Map(map) => Either::Right(map.keys()), } } @@ -147,8 +147,8 @@ impl SsoHashMap { /// The iterator element type is `&'a V`. pub fn values(&self) -> impl Iterator { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.iter().map(|(_k, v)| v)), - SsoHashMap::Map(map) => EitherIter::Right(map.values()), + SsoHashMap::Array(array) => Either::Left(array.iter().map(|(_k, v)| v)), + SsoHashMap::Map(map) => Either::Right(map.values()), } } @@ -156,8 +156,8 @@ impl SsoHashMap { /// The iterator element type is `&'a mut V`. pub fn values_mut(&mut self) -> impl Iterator { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.iter_mut().map(|(_k, v)| v)), - SsoHashMap::Map(map) => EitherIter::Right(map.values_mut()), + SsoHashMap::Array(array) => Either::Left(array.iter_mut().map(|(_k, v)| v)), + SsoHashMap::Map(map) => Either::Right(map.values_mut()), } } @@ -165,8 +165,8 @@ impl SsoHashMap { /// allocated memory for reuse. pub fn drain(&mut self) -> impl Iterator + '_ { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.drain(..)), - SsoHashMap::Map(map) => EitherIter::Right(map.drain()), + SsoHashMap::Array(array) => Either::Left(array.drain(..)), + SsoHashMap::Map(map) => Either::Right(map.drain()), } } } @@ -406,7 +406,7 @@ where } impl IntoIterator for SsoHashMap { - type IntoIter = EitherIter< + type IntoIter = Either< as IntoIterator>::IntoIter, as IntoIterator>::IntoIter, >; @@ -414,8 +414,8 @@ impl IntoIterator for SsoHashMap { fn into_iter(self) -> Self::IntoIter { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.into_iter()), - SsoHashMap::Map(map) => EitherIter::Right(map.into_iter()), + SsoHashMap::Array(array) => Either::Left(array.into_iter()), + SsoHashMap::Map(map) => Either::Right(map.into_iter()), } } } @@ -435,7 +435,7 @@ fn adapt_array_mut_it(pair: &mut (K, V)) -> (&K, &mut V) { } impl<'a, K, V> IntoIterator for &'a SsoHashMap { - type IntoIter = EitherIter< + type IntoIter = Either< std::iter::Map< <&'a ArrayVec<(K, V), 8> as IntoIterator>::IntoIter, fn(&'a (K, V)) -> (&'a K, &'a V), @@ -446,14 +446,14 @@ impl<'a, K, V> IntoIterator for &'a SsoHashMap { fn into_iter(self) -> Self::IntoIter { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.into_iter().map(adapt_array_ref_it)), - SsoHashMap::Map(map) => EitherIter::Right(map.iter()), + SsoHashMap::Array(array) => Either::Left(array.into_iter().map(adapt_array_ref_it)), + SsoHashMap::Map(map) => Either::Right(map.iter()), } } } impl<'a, K, V> IntoIterator for &'a mut SsoHashMap { - type IntoIter = EitherIter< + type IntoIter = Either< std::iter::Map< <&'a mut ArrayVec<(K, V), 8> as IntoIterator>::IntoIter, fn(&'a mut (K, V)) -> (&'a K, &'a mut V), @@ -464,8 +464,8 @@ impl<'a, K, V> IntoIterator for &'a mut SsoHashMap { fn into_iter(self) -> Self::IntoIter { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.into_iter().map(adapt_array_mut_it)), - SsoHashMap::Map(map) => EitherIter::Right(map.iter_mut()), + SsoHashMap::Array(array) => Either::Left(array.into_iter().map(adapt_array_mut_it)), + SsoHashMap::Map(map) => Either::Right(map.iter_mut()), } } } diff --git a/compiler/rustc_data_structures/src/sso/mod.rs b/compiler/rustc_data_structures/src/sso/mod.rs index dd21bc8e69636..ef634b9adcec3 100644 --- a/compiler/rustc_data_structures/src/sso/mod.rs +++ b/compiler/rustc_data_structures/src/sso/mod.rs @@ -1,4 +1,3 @@ -mod either_iter; mod map; mod set; From a32959263ca6b798fb02634d49e76c6abac41806 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 11 Apr 2023 10:56:35 +0000 Subject: [PATCH 2/2] Use `SSO_ARRAY_SIZE` instead of `8` in `SsoHashMap` impl --- compiler/rustc_data_structures/src/sso/map.rs | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_data_structures/src/sso/map.rs b/compiler/rustc_data_structures/src/sso/map.rs index f9e2dfd16d5c3..89b8c85264969 100644 --- a/compiler/rustc_data_structures/src/sso/map.rs +++ b/compiler/rustc_data_structures/src/sso/map.rs @@ -5,20 +5,20 @@ use std::fmt; use std::hash::Hash; use std::ops::Index; -// For pointer-sized arguments arrays -// are faster than set/map for up to 64 -// arguments. -// -// On the other hand such a big array -// hurts cache performance, makes passing -// sso structures around very expensive. -// -// Biggest performance benefit is gained -// for reasonably small arrays that stay -// small in vast majority of cases. -// -// '8' is chosen as a sane default, to be -// reevaluated later. +/// For pointer-sized arguments arrays +/// are faster than set/map for up to 64 +/// arguments. +/// +/// On the other hand such a big array +/// hurts cache performance, makes passing +/// sso structures around very expensive. +/// +/// Biggest performance benefit is gained +/// for reasonably small arrays that stay +/// small in vast majority of cases. +/// +/// '8' is chosen as a sane default, to be +/// reevaluated later. const SSO_ARRAY_SIZE: usize = 8; /// Small-storage-optimized implementation of a map. @@ -407,7 +407,7 @@ where impl IntoIterator for SsoHashMap { type IntoIter = Either< - as IntoIterator>::IntoIter, + as IntoIterator>::IntoIter, as IntoIterator>::IntoIter, >; type Item = ::Item; @@ -437,7 +437,7 @@ fn adapt_array_mut_it(pair: &mut (K, V)) -> (&K, &mut V) { impl<'a, K, V> IntoIterator for &'a SsoHashMap { type IntoIter = Either< std::iter::Map< - <&'a ArrayVec<(K, V), 8> as IntoIterator>::IntoIter, + <&'a ArrayVec<(K, V), SSO_ARRAY_SIZE> as IntoIterator>::IntoIter, fn(&'a (K, V)) -> (&'a K, &'a V), >, <&'a FxHashMap as IntoIterator>::IntoIter, @@ -455,7 +455,7 @@ impl<'a, K, V> IntoIterator for &'a SsoHashMap { impl<'a, K, V> IntoIterator for &'a mut SsoHashMap { type IntoIter = Either< std::iter::Map< - <&'a mut ArrayVec<(K, V), 8> as IntoIterator>::IntoIter, + <&'a mut ArrayVec<(K, V), SSO_ARRAY_SIZE> as IntoIterator>::IntoIter, fn(&'a mut (K, V)) -> (&'a K, &'a mut V), >, <&'a mut FxHashMap as IntoIterator>::IntoIter,