diff options
author | Christian Duerr <contact@christianduerr.com> | 2019-12-10 00:35:13 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-10 00:35:13 +0100 |
commit | 36185c47533d6189c9116df7a41a13766ca2b40c (patch) | |
tree | 80089a2da7de8701f59b1e692041f0de06c01aee /alacritty_terminal/src/grid/row.rs | |
parent | 79b19176eeb57fbd6b137160afd6bc9f5518ad33 (diff) | |
download | alacritty-36185c47533d6189c9116df7a41a13766ca2b40c.tar.gz alacritty-36185c47533d6189c9116df7a41a13766ca2b40c.zip |
Fix colored row reset performance
This fixes a bug where a row would always get reset completely if its
background does not equal the default terminal background. This leads to
big performance bottlenecks when running commands like `echo "\e[41m" &&
yes`.
Instead of resetting the entire row whenever the template cell is not
empty, the template cell is now compared to the last cell in the row.
The last cell will always be equal to the previous template cell when
`row.occ < row.inner.len()` and if `occ` is equal to the row's length,
the entire row is always reset anyways.
Fixes #2989.
Diffstat (limited to 'alacritty_terminal/src/grid/row.rs')
-rw-r--r-- | alacritty_terminal/src/grid/row.rs | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/alacritty_terminal/src/grid/row.rs b/alacritty_terminal/src/grid/row.rs index daee4408..0bfa88d4 100644 --- a/alacritty_terminal/src/grid/row.rs +++ b/alacritty_terminal/src/grid/row.rs @@ -29,14 +29,10 @@ use crate::index::Column; pub struct Row<T> { inner: Vec<T>, - /// occupied entries + /// Maximum number of occupied entries. /// - /// Semantically, this value can be understood as the **end** of an - /// Exclusive Range. Thus, - /// - /// - Zero means there are no occupied entries - /// - 1 means there is a value at index zero, but nowhere else - /// - `occ == inner.len` means every value is occupied + /// This is the upper bound on the number of elements in the row, which have been modified + /// since the last reset. All cells after this point are guaranteed to be equal. pub(crate) occ: usize, } @@ -85,21 +81,29 @@ impl<T: Copy> Row<T> { } } - /// Resets contents to the contents of `other` + /// Reset all cells in the row to the `template` cell. + #[inline] pub fn reset(&mut self, template: &T) where - T: GridCell, + T: GridCell + PartialEq, { - if template.is_empty() { - for item in &mut self.inner[..self.occ] { - *item = *template; - } - self.occ = 0; - } else { - let len = self.inner.len(); - self.inner = vec![*template; len]; + debug_assert!(!self.inner.is_empty()); + + let template = *template; + + // Mark all cells as dirty if template cell changed + let len = self.inner.len(); + if !self.inner[len - 1].fast_eq(template) { self.occ = len; } + + // Reset every dirty in the row + // let template = *template; + for item in &mut self.inner[..self.occ] { + *item = template; + } + + self.occ = 0; } } |