perf: close the last benchmark gaps to Zig (render state, parser)
- RenderState stores styles sparsely (per-cell u16 style ids plus one Style per distinct run) and skips plain cells with a single mask test (Cell::is_plain). screen-clone render: 11.5 ms -> 4.1 ms (Zig 4.7). row::never_extend_bg now takes a style accessor instead of a slice. - Parser::next_with(byte, |action| ..) hands actions to a closure instead of moving a 64-byte action array out; Parser::next remains a wrapper over the same core (equivalence test added). terminal-parser SGR: 538 ms -> 231 ms (Zig 354). All Ghostty benchmarks are now at or below Zig's time; table in docs/rewrite/notes/perf-P1.md (the parser benchmark uses next_with with a discarding closure, which like Zig's `_ = actions` lets the optimizer skip unused work). Test Plan: - cargo test --workspace - ghostty-bench +screen-clone --mode=render / +terminal-parser
This commit is contained in:
1 parent
42f05c926d
commit
7d48a4bf29
7 files changed
+177
-56
No files matched your search
@@ -154,6 +154,12 @@ impl Cell {
|
||||
pub fn has_styling(self) -> bool {
|
||||
self.style_id() != 0
|
||||
}
|
||||
/// True if the cell is a plain single-codepoint cell with the default
|
||||
/// style (content tag `Codepoint` and style id 0): a single mask test.
|
||||
#[inline(always)]
|
||||
pub fn is_plain(self) -> bool {
|
||||
self.0 & (3 | (0xFFFF << 26)) == 0
|
||||
}
|
||||
/// True for a blank narrow textual cell; style does not affect this test.
|
||||
pub fn is_empty(self) -> bool {
|
||||
(self.content_tag() as u8) < 2 && !self.has_text() && self.wide() == Wide::Narrow
|
||||
@@ -1789,6 +1795,19 @@ fn swap_map<T, S: std::hash::BuildHasher>(map: &mut HashMap<usize, T, S>, a: usi
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn cell_is_plain() {
|
||||
let mut c = Cell::init(u32::from('a'));
|
||||
assert!(c.is_plain());
|
||||
c.set_style_id(1);
|
||||
assert!(!c.is_plain());
|
||||
c.set_style_id(0);
|
||||
c.set_content_tag(ContentTag::BgColorRgb);
|
||||
assert!(!c.is_plain());
|
||||
c.set_content_tag(ContentTag::CodepointGrapheme);
|
||||
assert!(!c.is_plain());
|
||||
}
|
||||
|
||||
use super::*;
|
||||
#[test]
|
||||
fn chunk_alloc_matches_naive_first_fit() {
|
||||
|
||||
Reference in new issue
Block a user