mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-03 15:15:33 +00:00
perf: Reduce best fitting allocations (#7411)
This commit is contained in:
parent
2421805033
commit
3336d23f48
5 changed files with 173 additions and 83 deletions
|
@ -288,7 +288,9 @@ impl<'a> Printer<'a> {
|
|||
stack.push(TagKind::FitsExpanded, args);
|
||||
}
|
||||
|
||||
FormatElement::Tag(tag @ (StartLabelled(_) | StartEntry)) => {
|
||||
FormatElement::Tag(
|
||||
tag @ (StartLabelled(_) | StartEntry | StartBestFittingEntry { .. }),
|
||||
) => {
|
||||
stack.push(tag.kind(), args);
|
||||
}
|
||||
|
||||
|
@ -305,6 +307,7 @@ impl<'a> Printer<'a> {
|
|||
| EndFitsExpanded
|
||||
| EndVerbatim
|
||||
| EndLineSuffix
|
||||
| EndBestFittingEntry
|
||||
| EndFill),
|
||||
) => {
|
||||
stack.pop(tag.kind())?;
|
||||
|
@ -495,47 +498,64 @@ impl<'a> Printer<'a> {
|
|||
|
||||
if args.mode().is_flat() && self.state.measured_group_fits {
|
||||
queue.extend_back(variants.most_flat());
|
||||
self.print_entry(queue, stack, args)
|
||||
self.print_entry(queue, stack, args, TagKind::BestFittingEntry)
|
||||
} else {
|
||||
self.state.measured_group_fits = true;
|
||||
let normal_variants = &variants[..variants.len() - 1];
|
||||
let mut variants_iter = variants.into_iter();
|
||||
let mut current = variants_iter.next().unwrap();
|
||||
|
||||
for variant in normal_variants {
|
||||
for next in variants_iter {
|
||||
// Test if this variant fits and if so, use it. Otherwise try the next
|
||||
// variant.
|
||||
|
||||
// Try to fit only the first variant on a single line
|
||||
if !matches!(variant.first(), Some(&FormatElement::Tag(Tag::StartEntry))) {
|
||||
return invalid_start_tag(TagKind::Entry, variant.first());
|
||||
if !matches!(
|
||||
current.first(),
|
||||
Some(&FormatElement::Tag(Tag::StartBestFittingEntry))
|
||||
) {
|
||||
return invalid_start_tag(TagKind::BestFittingEntry, current.first());
|
||||
}
|
||||
|
||||
// Skip the first element because we want to override the args for the entry and the
|
||||
// args must be popped from the stack as soon as it sees the matching end entry.
|
||||
let content = &variant[1..];
|
||||
let content = ¤t[1..];
|
||||
|
||||
let entry_args = args
|
||||
.with_print_mode(PrintMode::Flat)
|
||||
.with_measure_mode(MeasureMode::from(mode));
|
||||
|
||||
queue.extend_back(content);
|
||||
stack.push(TagKind::Entry, entry_args);
|
||||
stack.push(TagKind::BestFittingEntry, entry_args);
|
||||
let variant_fits = self.fits(queue, stack)?;
|
||||
stack.pop(TagKind::Entry)?;
|
||||
stack.pop(TagKind::BestFittingEntry)?;
|
||||
|
||||
// Remove the content slice because printing needs the variant WITH the start entry
|
||||
let popped_slice = queue.pop_slice();
|
||||
debug_assert_eq!(popped_slice, Some(content));
|
||||
|
||||
if variant_fits {
|
||||
queue.extend_back(variant);
|
||||
return self.print_entry(queue, stack, args.with_print_mode(PrintMode::Flat));
|
||||
queue.extend_back(current);
|
||||
return self.print_entry(
|
||||
queue,
|
||||
stack,
|
||||
args.with_print_mode(PrintMode::Flat),
|
||||
TagKind::BestFittingEntry,
|
||||
);
|
||||
}
|
||||
|
||||
current = next;
|
||||
}
|
||||
|
||||
// At this stage current is the most expanded.
|
||||
|
||||
// No variant fits, take the last (most expanded) as fallback
|
||||
let most_expanded = variants.most_expanded();
|
||||
queue.extend_back(most_expanded);
|
||||
self.print_entry(queue, stack, args.with_print_mode(PrintMode::Expanded))
|
||||
queue.extend_back(current);
|
||||
self.print_entry(
|
||||
queue,
|
||||
stack,
|
||||
args.with_print_mode(PrintMode::Expanded),
|
||||
TagKind::BestFittingEntry,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -686,7 +706,7 @@ impl<'a> Printer<'a> {
|
|||
stack: &mut PrintCallStack,
|
||||
args: PrintElementArgs,
|
||||
) -> PrintResult<()> {
|
||||
self.print_entry(queue, stack, args)
|
||||
self.print_entry(queue, stack, args, TagKind::Entry)
|
||||
}
|
||||
|
||||
/// Semantic alias for [`Self::print_entry`] for fill separators.
|
||||
|
@ -696,7 +716,7 @@ impl<'a> Printer<'a> {
|
|||
stack: &mut PrintCallStack,
|
||||
args: PrintElementArgs,
|
||||
) -> PrintResult<()> {
|
||||
self.print_entry(queue, stack, args)
|
||||
self.print_entry(queue, stack, args, TagKind::Entry)
|
||||
}
|
||||
|
||||
/// Fully print an element (print the element itself and all its descendants)
|
||||
|
@ -708,32 +728,31 @@ impl<'a> Printer<'a> {
|
|||
queue: &mut PrintQueue<'a>,
|
||||
stack: &mut PrintCallStack,
|
||||
args: PrintElementArgs,
|
||||
kind: TagKind,
|
||||
) -> PrintResult<()> {
|
||||
let start_entry = queue.top();
|
||||
|
||||
if !matches!(start_entry, Some(&FormatElement::Tag(Tag::StartEntry))) {
|
||||
return invalid_start_tag(TagKind::Entry, start_entry);
|
||||
if queue
|
||||
.pop()
|
||||
.is_some_and(|start| start.tag_kind() == Some(kind))
|
||||
{
|
||||
stack.push(kind, args);
|
||||
} else {
|
||||
return invalid_start_tag(kind, start_entry);
|
||||
}
|
||||
|
||||
let mut depth = 0;
|
||||
let mut depth = 1u32;
|
||||
|
||||
while let Some(element) = queue.pop() {
|
||||
match element {
|
||||
FormatElement::Tag(Tag::StartEntry) => {
|
||||
// Handle the start of the first element by pushing the args on the stack.
|
||||
if depth == 0 {
|
||||
depth = 1;
|
||||
stack.push(TagKind::Entry, args);
|
||||
continue;
|
||||
}
|
||||
|
||||
FormatElement::Tag(Tag::StartEntry | Tag::StartBestFittingEntry) => {
|
||||
depth += 1;
|
||||
}
|
||||
FormatElement::Tag(Tag::EndEntry) => {
|
||||
FormatElement::Tag(end_tag @ (Tag::EndEntry | Tag::EndBestFittingEntry)) => {
|
||||
depth -= 1;
|
||||
// Reached the end entry, pop the entry from the stack and return.
|
||||
if depth == 0 {
|
||||
stack.pop(TagKind::Entry)?;
|
||||
stack.pop(end_tag.kind())?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
@ -745,7 +764,7 @@ impl<'a> Printer<'a> {
|
|||
self.print_element(stack, queue, element)?;
|
||||
}
|
||||
|
||||
invalid_end_tag(TagKind::Entry, stack.top_kind())
|
||||
invalid_end_tag(kind, stack.top_kind())
|
||||
}
|
||||
|
||||
fn print_char(&mut self, char: char) {
|
||||
|
@ -1148,11 +1167,14 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
|
|||
PrintMode::Expanded => (variants.most_expanded(), args),
|
||||
};
|
||||
|
||||
if !matches!(slice.first(), Some(FormatElement::Tag(Tag::StartEntry))) {
|
||||
return invalid_start_tag(TagKind::Entry, slice.first());
|
||||
if !matches!(
|
||||
slice.first(),
|
||||
Some(FormatElement::Tag(Tag::StartBestFittingEntry))
|
||||
) {
|
||||
return invalid_start_tag(TagKind::BestFittingEntry, slice.first());
|
||||
}
|
||||
|
||||
self.stack.push(TagKind::Entry, args);
|
||||
self.stack.push(TagKind::BestFittingEntry, args);
|
||||
self.queue.extend_back(&slice[1..]);
|
||||
}
|
||||
|
||||
|
@ -1277,7 +1299,11 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
|
|||
}
|
||||
|
||||
FormatElement::Tag(
|
||||
tag @ (StartFill | StartVerbatim(_) | StartLabelled(_) | StartEntry),
|
||||
tag @ (StartFill
|
||||
| StartVerbatim(_)
|
||||
| StartLabelled(_)
|
||||
| StartEntry
|
||||
| StartBestFittingEntry { .. }),
|
||||
) => {
|
||||
self.stack.push(tag.kind(), args);
|
||||
}
|
||||
|
@ -1294,6 +1320,7 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
|
|||
| EndAlign
|
||||
| EndDedent
|
||||
| EndIndent
|
||||
| EndBestFittingEntry
|
||||
| EndFitsExpanded),
|
||||
) => {
|
||||
self.stack.pop(tag.kind())?;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue