Benchmark inserting a line at the beginning of moby dick
This commit is contained in:
parent
a2146a0168
commit
24d266ab34
|
@ -12,3 +12,8 @@ serde = { version = "1", features = [ "derive" ] }
|
||||||
serde_yml = { version = "*" }
|
serde_yml = { version = "*" }
|
||||||
thiserror = { version = "1" }
|
thiserror = { version = "1" }
|
||||||
tui = { version = "0.19", default-features = false, features = [ "crossterm", "serde" ] }
|
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
|
@ -0,0 +1,5 @@
|
||||||
|
use editor_challenge::types::bench::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
bench_insert_lines();
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
pub mod ui;
|
||||||
|
pub mod state;
|
||||||
|
pub mod types;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
mod ui;
|
|
||||||
mod state;
|
|
||||||
mod types;
|
|
||||||
|
|
||||||
use ui::Canvas;
|
|
||||||
use crossterm::event::{self, KeyCode, KeyEvent, KeyModifiers};
|
use crossterm::event::{self, KeyCode, KeyEvent, KeyModifiers};
|
||||||
|
use editor_challenge::*;
|
||||||
use state::AppState;
|
use state::AppState;
|
||||||
use std::{
|
use std::{
|
||||||
env, io,
|
env, io,
|
||||||
|
@ -12,6 +8,7 @@ use std::{
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
use tui::{backend::CrosstermBackend, Terminal};
|
use tui::{backend::CrosstermBackend, Terminal};
|
||||||
|
use ui::Canvas;
|
||||||
|
|
||||||
// const TITLE: &str = "Text Editor Challenge";
|
// const TITLE: &str = "Text Editor Challenge";
|
||||||
// const COPYRIGHT: &str = "(c) Savanni D'Gerinel - all rights reserved";
|
// const COPYRIGHT: &str = "(c) Savanni D'Gerinel - all rights reserved";
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
|
|
||||||
// TODO: I'm increasingly feeling that cursors are per-document, not per-application. So I think I
|
// 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
|
// want to move the cursor into here, and then rendering requires asking for the cursor for the
|
||||||
// current document.
|
// current document.
|
||||||
#[derive(Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct Document {
|
pub struct Document {
|
||||||
rows: Vec<String>
|
rows: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Document {
|
impl Document {
|
||||||
|
@ -12,9 +11,7 @@ impl Document {
|
||||||
if contents.len() > (u16::MAX.into()) {
|
if contents.len() > (u16::MAX.into()) {
|
||||||
panic!("Document row count exceeds u16::MAX. The current scrolling code cannot handle that.");
|
panic!("Document row count exceeds u16::MAX. The current scrolling code cannot handle that.");
|
||||||
}
|
}
|
||||||
Self{
|
Self { rows: contents }
|
||||||
rows: contents
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contents(&self) -> String {
|
pub fn contents(&self) -> String {
|
||||||
|
@ -29,7 +26,7 @@ impl Document {
|
||||||
self.rows.len()
|
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();
|
let (row, column) = cursor.addr();
|
||||||
|
|
||||||
self.rows[row].insert(column, c);
|
self.rows[row].insert(column, c);
|
||||||
|
@ -110,7 +107,86 @@ impl Cursor {
|
||||||
}
|
}
|
||||||
self.desired_column = self.column;
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue