From 09987c1d27935dc22ba1453cd77a8e04dd47a819 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Fri, 3 Nov 2023 17:32:39 +0900 Subject: [PATCH] merge: micro-optimize allocation of Merge object for resolved value It's super common that a Merge object holds a resolved value, so let's inline up to 1 element. T of Merge usually consists of a couple of pointer-sized fields. I don't see any measurable speed up, but it's no worse than the original. --- lib/src/merge.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/src/merge.rs b/lib/src/merge.rs index cc7d3aca3..6cf1bcdfa 100644 --- a/lib/src/merge.rs +++ b/lib/src/merge.rs @@ -21,10 +21,11 @@ use std::fmt::{Debug, Formatter}; use std::hash::Hash; use std::io::Write; use std::iter::zip; +use std::slice; use std::sync::Arc; -use std::{slice, vec}; use itertools::Itertools; +use smallvec::{smallvec_inline, SmallVec}; use crate::backend; use crate::backend::{BackendError, FileId, ObjectId, TreeId, TreeValue}; @@ -115,7 +116,7 @@ where #[derive(PartialEq, Eq, Hash, Clone)] pub struct Merge { /// Alternates between positive and negative terms, starting with positive. - values: Vec, + values: SmallVec<[T; 1]>, } impl Debug for Merge { @@ -143,7 +144,7 @@ impl Merge { /// Creates a `Merge` with a single resolved value. pub fn resolved(value: T) -> Self { Merge { - values: vec![value], + values: smallvec_inline![value], } } @@ -321,7 +322,7 @@ impl Merge { /// the checking until after `from_iter()` (to `MergeBuilder::build()`). #[derive(Clone, Debug, PartialEq, Eq)] pub struct MergeBuilder { - values: Vec, + values: SmallVec<[T; 1]>, } impl Default for MergeBuilder { @@ -345,7 +346,7 @@ impl MergeBuilder { impl IntoIterator for Merge { type Item = T; - type IntoIter = vec::IntoIter; + type IntoIter = smallvec::IntoIter<[T; 1]>; fn into_iter(self) -> Self::IntoIter { self.values.into_iter()