Benchmark inserting a line at the beginning of moby dick

This commit is contained in:
Savanni D'Gerinel 2024-05-06 09:27:37 -04:00
parent a2146a0168
commit 24d266ab34
6 changed files with 22417 additions and 13 deletions

View File

@ -12,3 +12,8 @@ serde = { version = "1", features = [ "derive" ] }
serde_yml = { version = "*" }
thiserror = { version = "1" }
tui = { version = "0.19", default-features = false, features = [ "crossterm", "serde" ] }
[[bin]]
name = "bench"
main = "bin/bench.rs"
features = [ "bench" ]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
use editor_challenge::types::bench::*;
fn main() {
bench_insert_lines();
}

View File

@ -0,0 +1,5 @@
pub mod ui;
pub mod state;
pub mod types;

View File

@ -1,9 +1,5 @@
mod ui;
mod state;
mod types;
use ui::Canvas;
use crossterm::event::{self, KeyCode, KeyEvent, KeyModifiers};
use editor_challenge::*;
use state::AppState;
use std::{
env, io,
@ -12,6 +8,7 @@ use std::{
time::{Duration, Instant},
};
use tui::{backend::CrosstermBackend, Terminal};
use ui::Canvas;
// const TITLE: &str = "Text Editor Challenge";
// const COPYRIGHT: &str = "(c) Savanni D'Gerinel - all rights reserved";

View File

@ -1,10 +1,9 @@
// TODO: I'm increasingly feeling that cursors are per-document, not per-application. So I think I
// want to move the cursor into here, and then rendering requires asking for the cursor for the
// current document.
#[derive(Default)]
#[derive(Clone, Default)]
pub struct Document {
rows: Vec<String>
rows: Vec<String>,
}
impl Document {
@ -12,9 +11,7 @@ impl Document {
if contents.len() > (u16::MAX.into()) {
panic!("Document row count exceeds u16::MAX. The current scrolling code cannot handle that.");
}
Self{
rows: contents
}
Self { rows: contents }
}
pub fn contents(&self) -> String {
@ -29,7 +26,7 @@ impl Document {
self.rows.len()
}
pub fn insert_at(&mut self, cursor: &mut Cursor, c: char){
pub fn insert_at(&mut self, cursor: &mut Cursor, c: char) {
let (row, column) = cursor.addr();
self.rows[row].insert(column, c);
@ -110,7 +107,86 @@ impl Cursor {
}
self.desired_column = self.column;
}
}
mod test_utils {
use super::*;
use std::{
fs::File,
io::{BufRead, BufReader},
time::{Duration, Instant},
};
pub fn with_file<F>(test: F)
where
F: FnOnce(Document),
{
let f = File::open("fixtures/moby-dick.txt").unwrap();
let reader = BufReader::new(f);
let contents = reader
.lines()
.collect::<Result<Vec<String>, std::io::Error>>()
.unwrap();
let doc = Document::new(contents);
test(doc);
}
pub fn measure<F>(test: F) -> Duration
where
F: FnOnce(),
{
let start = Instant::now();
test();
let end = Instant::now();
end - start
}
pub fn benchmark<A>(
num_iterations: usize,
setup: impl Fn() -> A,
test: impl FnOnce(A) + Copy,
) -> Duration {
let mut measurements: Duration = Duration::from_millis(0);
for _i in 0..num_iterations {
let data = setup();
measurements += measure(move || test(data))
}
measurements / (num_iterations as u32)
}
}
#[cfg(test)]
mod test {
use super::{test_utils::*, *};
#[test]
fn it_inserts_a_line() {
with_file(|mut doc| {
let mut cursor = Cursor::default();
let num_lines = doc.row_count();
doc.new_line(&mut cursor);
assert_eq!(doc.row_count(), num_lines + 1);
});
}
}
pub mod bench {
use super::{test_utils::*, *};
pub fn bench_insert_lines() {
with_file(|doc| {
let performance = benchmark(
1000,
|| doc.clone(),
|mut doc| {
let mut cursor = Cursor::default();
doc.new_line(&mut cursor);
},
);
println!("[bench_insert_lines] {:?}", performance);
});
}
}