perf(diagnostics): reduce graphical rendering allocations (#25711)

Keep common graphical-rendering buffers inline and add a focused
benchmark for regressions.

AI assistance: Codex was used. The contributor remains responsible for
this change.

<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a></sub>
This commit is contained in:
Boshen authored and GitHub committed 2026-08-16 19:06:16 +08:00
1 parent 9c8abab7a7
commit 10fc4b7d33
3 files changed
+8 -5

No files matched your search

@@ -13,6 +13,7 @@ use std::{
};
use owo_colors::{OwoColorize, Style};
use smallvec::SmallVec;
use super::{
handler::GraphicalReportHandler,
@@ -133,7 +134,7 @@ impl GraphicalReportHandler {
let mut highest = 0;
let chars = &self.theme.characters;
let mut vbar_offsets = Vec::with_capacity(single_liners.len());
let mut vbar_offsets = SmallVec::<[_; 2]>::with_capacity(single_liners.len());
for &hl in single_liners {
let byte_start = hl.offset();
let byte_end = hl.offset() + hl.len();
@@ -12,6 +12,7 @@
use std::str::{CharIndices, from_utf8};
use smallvec::SmallVec;
use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;
@@ -203,7 +204,7 @@ impl GraphicalReportHandler {
}
/// Splits already-scanned span contents into [`Line`]s.
pub(super) fn get_lines<'a>(context_data: &SpanContents<'a>) -> Vec<Line<'a>> {
pub(super) fn get_lines<'a>(context_data: &SpanContents<'a>) -> SmallVec<[Line<'a>; 3]> {
let context = from_utf8(context_data.data()).expect("Bad utf8 detected");
let mut line = context_data.line();
let base = context_data.span().start as usize;
@@ -213,7 +214,7 @@ impl GraphicalReportHandler {
// Cap the hint by byte length because custom sources own this metadata.
let capacity =
context_data.line_count().saturating_sub(context_data.line()).max(1).min(bytes.len());
let mut lines = Vec::with_capacity(capacity);
let mut lines = SmallVec::with_capacity(capacity);
let mut start = 0;
for newline in memchr::memchr_iter(b'\n', bytes) {
let end = newline + 1;
@@ -11,6 +11,7 @@
use std::{borrow::Cow, cmp::max, fmt};
use owo_colors::OwoColorize;
use smallvec::SmallVec;
use super::{
handler::GraphicalReportHandler,
@@ -112,7 +113,7 @@ impl GraphicalReportHandler {
.copied()
.zip(self.theme.styles.highlights.iter().copied().cycle())
.map(|(label, style)| FancySpan::new(label.label(), label.span(), style))
.collect::<Vec<_>>();
.collect::<SmallVec<[_; 2]>>();
// Find the maximum number of active gutter lines to determine indentation.
let mut max_gutter = 0usize;
@@ -166,7 +167,7 @@ impl GraphicalReportHandler {
self.render_line_gutter(f, max_gutter, line, &labels)?;
Self::render_line_text(f, line.text)?;
let (single_line, multi_line): (Vec<_>, Vec<_>) = labels
let (single_line, multi_line): (SmallVec<[_; 2]>, SmallVec<[_; 2]>) = labels
.iter()
.filter(|hl| line.span_applies(hl))
.partition(|hl| line.span_line_only(hl));