Skip to content

Commit 90e4f1f

Browse files
committed
refactor(deserialize): exact allocation for arrays
1 parent 78011b1 commit 90e4f1f

File tree

3 files changed

+44
-20
lines changed

3 files changed

+44
-20
lines changed

crates/biome_deserialize/src/impls.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -510,15 +510,15 @@ impl<T: Deserializable> Deserializable for Vec<T> {
510510
fn visit_array(
511511
self,
512512
ctx: &mut impl DeserializationContext,
513-
values: impl Iterator<Item = Option<impl DeserializableValue>>,
513+
values: impl ExactSizeIterator<Item = Option<impl DeserializableValue>>,
514514
_range: TextRange,
515515
_name: &str,
516516
) -> Option<Self::Output> {
517-
Some(
518-
values
519-
.filter_map(|value| Deserializable::deserialize(ctx, &value?, ""))
520-
.collect(),
521-
)
517+
let mut result = Vec::with_capacity(values.len());
518+
result.extend(
519+
values.filter_map(|value| Deserializable::deserialize(ctx, &value?, "")),
520+
);
521+
Some(result)
522522
}
523523
}
524524
value.deserialize(ctx, Visitor(PhantomData), name)
@@ -549,7 +549,7 @@ impl<T: Deserializable, const L: usize> Deserializable for smallvec::SmallVec<[T
549549
fn visit_array(
550550
self,
551551
ctx: &mut impl DeserializationContext,
552-
values: impl Iterator<Item = Option<impl DeserializableValue>>,
552+
values: impl ExactSizeIterator<Item = Option<impl DeserializableValue>>,
553553
_range: TextRange,
554554
_name: &str,
555555
) -> Option<Self::Output> {
@@ -579,7 +579,7 @@ impl<T: Deserializable + Eq + Hash, S: BuildHasher + Default> Deserializable for
579579
fn visit_array(
580580
self,
581581
ctx: &mut impl DeserializationContext,
582-
values: impl Iterator<Item = Option<impl DeserializableValue>>,
582+
values: impl ExactSizeIterator<Item = Option<impl DeserializableValue>>,
583583
_range: TextRange,
584584
_name: &str,
585585
) -> Option<Self::Output> {
@@ -607,7 +607,7 @@ impl<T: Ord + Deserializable> Deserializable for BTreeSet<T> {
607607
fn visit_array(
608608
self,
609609
ctx: &mut impl DeserializationContext,
610-
values: impl Iterator<Item = Option<impl DeserializableValue>>,
610+
values: impl ExactSizeIterator<Item = Option<impl DeserializableValue>>,
611611
_range: TextRange,
612612
_name: &str,
613613
) -> Option<Self::Output> {
@@ -636,15 +636,15 @@ impl<T: Hash + Eq + Deserializable> Deserializable for indexmap::IndexSet<T> {
636636
fn visit_array(
637637
self,
638638
ctx: &mut impl DeserializationContext,
639-
values: impl Iterator<Item = Option<impl DeserializableValue>>,
639+
values: impl ExactSizeIterator<Item = Option<impl DeserializableValue>>,
640640
_range: TextRange,
641641
_name: &str,
642642
) -> Option<Self::Output> {
643-
Some(
644-
values
645-
.filter_map(|value| Deserializable::deserialize(ctx, &value?, ""))
646-
.collect(),
647-
)
643+
let mut result = indexmap::IndexSet::with_capacity(values.len());
644+
result.extend(
645+
values.filter_map(|value| Deserializable::deserialize(ctx, &value?, "")),
646+
);
647+
Some(result)
648648
}
649649
}
650650
value.deserialize(ctx, Visitor(PhantomData), name)
@@ -668,7 +668,7 @@ impl<K: Hash + Eq + Deserializable, V: Deserializable, S: Default + BuildHasher>
668668
fn visit_map(
669669
self,
670670
ctx: &mut impl DeserializationContext,
671-
members: impl Iterator<
671+
members: impl ExactSizeIterator<
672672
Item = Option<(impl DeserializableValue, impl DeserializableValue)>,
673673
>,
674674
_range: TextRange,
@@ -702,7 +702,7 @@ impl<K: Ord + Deserializable, V: Deserializable> Deserializable for BTreeMap<K,
702702
fn visit_map(
703703
self,
704704
ctx: &mut impl DeserializationContext,
705-
members: impl Iterator<
705+
members: impl ExactSizeIterator<
706706
Item = Option<(impl DeserializableValue, impl DeserializableValue)>,
707707
>,
708708
_range: TextRange,
@@ -741,7 +741,7 @@ impl<K: Hash + Eq + Deserializable, V: Deserializable, S: Default + BuildHasher>
741741
fn visit_map(
742742
self,
743743
ctx: &mut impl DeserializationContext,
744-
members: impl Iterator<
744+
members: impl ExactSizeIterator<
745745
Item = Option<(impl DeserializableValue, impl DeserializableValue)>,
746746
>,
747747
_range: TextRange,

crates/biome_deserialize/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ pub trait DeserializationVisitor: Sized {
398398
fn visit_array(
399399
self,
400400
ctx: &mut impl DeserializationContext,
401-
_items: impl Iterator<Item = Option<impl DeserializableValue>>,
401+
_items: impl ExactSizeIterator<Item = Option<impl DeserializableValue>>,
402402
range: TextRange,
403403
name: &str,
404404
) -> Option<Self::Output> {
@@ -422,7 +422,9 @@ pub trait DeserializationVisitor: Sized {
422422
fn visit_map(
423423
self,
424424
ctx: &mut impl DeserializationContext,
425-
_members: impl Iterator<Item = Option<(impl DeserializableValue, impl DeserializableValue)>>,
425+
_members: impl ExactSizeIterator<
426+
Item = Option<(impl DeserializableValue, impl DeserializableValue)>,
427+
>,
426428
range: TextRange,
427429
name: &str,
428430
) -> Option<Self::Output> {

crates/biome_rowan/src/ast/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,19 @@ impl<L: Language, N: AstNode<Language = L>> Iterator for AstSeparatedListElement
683683
trailing_separator: separator,
684684
})
685685
}
686+
687+
fn size_hint(&self) -> (usize, Option<usize>) {
688+
let len = self.slots.len();
689+
// Each element typically consumes 2 slots (node + separator),
690+
// but the last element may have only 1 slot (node without trailing separator)
691+
let len = len.div_ceil(2);
692+
(len, Some(len))
693+
}
694+
}
695+
696+
impl<L: Language, N: AstNode<Language = L>> ExactSizeIterator
697+
for AstSeparatedListElementsIterator<L, N>
698+
{
686699
}
687700

688701
impl<L: Language, N: AstNode<Language = L>> FusedIterator
@@ -736,6 +749,15 @@ impl<L: Language, N: AstNode<Language = L>> Iterator for AstSeparatedListNodesIt
736749
fn next(&mut self) -> Option<Self::Item> {
737750
self.inner.next().map(|element| element.node)
738751
}
752+
753+
fn size_hint(&self) -> (usize, Option<usize>) {
754+
self.inner.size_hint()
755+
}
756+
}
757+
758+
impl<L: Language, N: AstNode<Language = L>> ExactSizeIterator
759+
for AstSeparatedListNodesIterator<L, N>
760+
{
739761
}
740762

741763
impl<L: Language, N: AstNode<Language = L>> FusedIterator for AstSeparatedListNodesIterator<L, N> {}

0 commit comments

Comments
 (0)