-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add stdout / stderr performance to FAQ #274
Comments
I found the same thing happening in a game of life tui, i.e. |
I didn't go through all the discussion but do we know why this is happening? Some underlying crossterm implementation difference? |
I believe @orhun is planning submit a PR to |
Yes, the trick is to make the internal buffer of the backend buffered via Diffdiff --git a/src/backend/crossterm.rs b/src/backend/crossterm.rs
index b35c3af..0162d4e 100644
--- a/src/backend/crossterm.rs
+++ b/src/backend/crossterm.rs
@@ -2,7 +2,7 @@
//! the [Crossterm] crate to interact with the terminal.
//!
//! [Crossterm]: https://crates.io/crates/crossterm
-use std::io::{self, Write};
+use std::io::{self, LineWriter, Write};
#[cfg(feature = "underline-color")]
use crossterm::style::SetUnderlineColor;
@@ -78,10 +78,10 @@ use crate::{
/// [`backend`]: crate::backend
/// [Crossterm]: https://crates.io/crates/crossterm
/// [examples]: https://github.com/ratatui-org/ratatui/tree/main/examples#examples
-#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
+#[derive(Debug)]
pub struct CrosstermBackend<W: Write> {
/// The writer used to send commands to the terminal.
- writer: W,
+ writer: LineWriter<W>,
}
impl<W> CrosstermBackend<W>
@@ -98,7 +98,9 @@ where
/// let backend = CrosstermBackend::new(stdout());
/// ```
pub fn new(writer: W) -> CrosstermBackend<W> {
- CrosstermBackend { writer }
+ CrosstermBackend {
+ writer: LineWriter::new(writer),
+ }
}
} But the downside is, both Another option is to implement a custom buffered writer: Diffdiff --git a/src/backend/crossterm.rs b/src/backend/crossterm.rs
index b35c3af..849fb8a 100644
--- a/src/backend/crossterm.rs
+++ b/src/backend/crossterm.rs
@@ -81,7 +81,7 @@ use crate::{
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
pub struct CrosstermBackend<W: Write> {
/// The writer used to send commands to the terminal.
- writer: W,
+ writer: CustomWriter<W>,
}
impl<W> CrosstermBackend<W>
@@ -98,17 +98,37 @@ where
/// let backend = CrosstermBackend::new(stdout());
/// ```
pub fn new(writer: W) -> CrosstermBackend<W> {
- CrosstermBackend { writer }
+ CrosstermBackend {
+ writer: CustomWriter {
+ writer,
+ buffer: Vec::new(),
+ },
+ }
}
}
-impl<W> Write for CrosstermBackend<W>
+const BUFFER_SIZE: usize = 8096;
+
+#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
+struct CustomWriter<W: Write> {
+ pub writer: W,
+ pub buffer: Vec<u8>,
+}
+
+impl<W> Write for CustomWriter<W>
where
W: Write,
{
/// Writes a buffer of bytes to the underlying buffer.
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- self.writer.write(buf)
+ self.buffer.extend(buf);
+ if self.buffer.len() >= BUFFER_SIZE {
+ let n = self.writer.write(buf)?;
+ self.writer.flush()?;
+ Ok(n)
+ } else {
+ Ok(buf.len())
+ }
}
/// Flushes the underlying buffer. But this is suboptimal since additional maintenance burden + needs more optimizations. |
I suspect that it might be better to let the user handle this by wrapping their writer outside of Ratatui. |
Yes, I think the best thing to do here is to update the documentation about the difference between stdout and stderr & mention how to achieve the same performance. |
https://ratatui.rs/faq/#should-i-use-stdout-or-stderr
See ratatui-org/ratatui#583 (comment)
Valentin271 Dec 13, 2023
Oh that's interesting, stdout is also faster on my machine
If this is consistent, we might want to keep that in mind. We currently use stderr in the template. And we should mention that in the FAQ
The text was updated successfully, but these errors were encountered: