зеркало из
https://github.com/glebtv/tui-textarea.git
synced 2026-09-03 14:26:17 +03:00
explicitly use subslice of lines
this improved performance by 2~5%
```
insert::append::1_lorem time: [7.0412 ms 7.0825 ms 7.1268 ms]
change: [-8.5796% -7.8935% -7.1723%] (p = 0.00 < 0.05)
Performance has improved.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
Benchmarking insert::append::10_lorem: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 33.6s, or reduce sample count to 10.
insert::append::10_lorem
time: [328.15 ms 329.60 ms 331.12 ms]
change: [-9.6975% -9.1606% -8.6231%] (p = 0.00 < 0.05)
Performance has improved.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
Benchmarking insert::append::50_lorem: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 321.1s, or reduce sample count to 10.
insert::append::50_lorem
time: [3.1633 s 3.1727 s 3.1826 s]
change: [-7.3473% -7.0339% -6.6629%] (p = 0.00 < 0.05)
Performance has improved.
```
Этот коммит содержится в:
@@ -1,5 +1,6 @@
|
||||
use crate::textarea::TextArea;
|
||||
use crate::util::num_digits;
|
||||
use std::cmp;
|
||||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
use tui::buffer::Buffer;
|
||||
use tui::layout::Rect;
|
||||
@@ -42,6 +43,18 @@ impl<'a> Renderer<'a> {
|
||||
pub fn new(textarea: &'a TextArea<'a>) -> Self {
|
||||
Self(textarea)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn text(&self, top_row: usize, height: usize) -> Text<'a> {
|
||||
let lines_len = self.0.lines().len();
|
||||
let lnum_len = num_digits(lines_len);
|
||||
let bottom_row = cmp::min(top_row + height, lines_len);
|
||||
let mut lines = Vec::with_capacity(bottom_row - top_row);
|
||||
for (i, line) in self.0.lines()[top_row..bottom_row].iter().enumerate() {
|
||||
lines.push(self.0.line_spans(line.as_str(), top_row + i, lnum_len));
|
||||
}
|
||||
Text::from(lines)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Widget for Renderer<'a> {
|
||||
@@ -64,31 +77,20 @@ impl<'a> Widget for Renderer<'a> {
|
||||
|
||||
let cursor = self.0.cursor();
|
||||
let (top_row, top_col) = self.0.scroll_top.load();
|
||||
let row = next_scroll_top(top_row, cursor.0 as u16, inner_area.height);
|
||||
let col = next_scroll_top(top_col, cursor.1 as u16, inner_area.width);
|
||||
let top_row = next_scroll_top(top_row, cursor.0 as u16, inner_area.height);
|
||||
let top_col = next_scroll_top(top_col, cursor.1 as u16, inner_area.width);
|
||||
|
||||
let lnum_len = num_digits(self.0.lines().len());
|
||||
let lines: Vec<_> = self
|
||||
.0
|
||||
.lines()
|
||||
.iter()
|
||||
.map(String::as_str)
|
||||
.enumerate()
|
||||
.skip(row as usize)
|
||||
.take(inner_area.height as usize)
|
||||
.map(|(row, line)| self.0.line_spans(line, row, lnum_len))
|
||||
.collect();
|
||||
|
||||
let mut inner = Paragraph::new(Text::from(lines)).style(self.0.style());
|
||||
let text = self.text(top_row as usize, inner_area.height as usize);
|
||||
let mut inner = Paragraph::new(text).style(self.0.style());
|
||||
if let Some(b) = self.0.block() {
|
||||
inner = inner.block(b.clone());
|
||||
}
|
||||
if col != 0 {
|
||||
inner = inner.scroll((0, col));
|
||||
if top_col != 0 {
|
||||
inner = inner.scroll((0, top_col));
|
||||
}
|
||||
|
||||
// Store scroll top position for rendering on the next tick
|
||||
self.0.scroll_top.store(row, col);
|
||||
self.0.scroll_top.store(top_row, top_col);
|
||||
|
||||
inner.render(area, buf);
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user