#[cfg(test)]
mod render_op_benchmarks {
extern crate test;
use smallvec::SmallVec;
use test::Bencher;
use crate::{AnsiValue, InlineString, Pos, RenderOp, RgbValue, TuiColor, TuiStyle, ch};
type RenderOpsSmallVec = SmallVec<[RenderOp; 8]>;
type RenderOpsVec = Vec<RenderOp>;
fn create_test_render_ops() -> Vec<RenderOp> {
vec![
RenderOp::ClearScreen,
RenderOp::ResetColor,
RenderOp::MoveCursorPositionAbs(Pos {
row_index: ch(10).into(),
col_index: ch(20).into(),
}),
RenderOp::SetFgColor(TuiColor::Rgb(RgbValue::from_u8(255, 128, 64))),
RenderOp::SetBgColor(TuiColor::Ansi(AnsiValue::new(42))),
RenderOp::PaintTextWithAttributes(
InlineString::from("Hello, World!"),
Some(TuiStyle {
color_fg: Some(TuiColor::Rgb(RgbValue::from_u8(200, 200, 200))),
color_bg: Some(TuiColor::Ansi(AnsiValue::new(232))),
..Default::default()
}),
),
RenderOp::MoveCursorPositionRelTo(
Pos {
row_index: ch(5).into(),
col_index: ch(10).into(),
},
Pos {
row_index: ch(2).into(),
col_index: ch(3).into(),
},
),
RenderOp::ApplyColors(Some(TuiStyle {
color_fg: Some(TuiColor::Rgb(RgbValue::from_u8(100, 100, 100))),
color_bg: Some(TuiColor::Ansi(AnsiValue::new(16))),
..Default::default()
})),
]
}
#[bench]
fn bench_smallvec_push_typical(b: &mut Bencher) {
let ops = create_test_render_ops();
b.iter(|| {
let mut collection = RenderOpsSmallVec::new();
for op in &ops {
collection.push(op.clone());
}
test::black_box(collection)
});
}
#[bench]
fn bench_vec_push_typical(b: &mut Bencher) {
let ops = create_test_render_ops();
b.iter(|| {
let mut collection = RenderOpsVec::new();
for op in &ops {
collection.push(op.clone());
}
test::black_box(collection)
});
}
#[bench]
fn bench_vec_with_capacity_push_typical(b: &mut Bencher) {
let ops = create_test_render_ops();
b.iter(|| {
let mut collection = RenderOpsVec::with_capacity(8);
for op in &ops {
collection.push(op.clone());
}
test::black_box(collection)
});
}
#[bench]
fn bench_smallvec_push_complex(b: &mut Bencher) {
let base_ops = create_test_render_ops();
let mut ops = Vec::new();
for _ in 0..3 {
ops.extend_from_slice(&base_ops);
}
ops.truncate(20);
b.iter(|| {
let mut collection = RenderOpsSmallVec::new();
for op in &ops {
collection.push(op.clone());
}
test::black_box(collection)
});
}
#[bench]
fn bench_vec_push_complex(b: &mut Bencher) {
let base_ops = create_test_render_ops();
let mut ops = Vec::new();
for _ in 0..3 {
ops.extend_from_slice(&base_ops);
}
ops.truncate(20);
b.iter(|| {
let mut collection = RenderOpsVec::new();
for op in &ops {
collection.push(op.clone());
}
test::black_box(collection)
});
}
#[bench]
fn bench_vec_with_capacity_push_complex(b: &mut Bencher) {
let base_ops = create_test_render_ops();
let mut ops = Vec::new();
for _ in 0..3 {
ops.extend_from_slice(&base_ops);
}
ops.truncate(20);
b.iter(|| {
let mut collection = RenderOpsVec::with_capacity(20);
for op in &ops {
collection.push(op.clone());
}
test::black_box(collection)
});
}
#[bench]
fn bench_smallvec_extend(b: &mut Bencher) {
let ops = create_test_render_ops();
b.iter(|| {
let mut collection = RenderOpsSmallVec::new();
collection.extend(ops.iter().cloned());
test::black_box(collection)
});
}
#[bench]
fn bench_vec_extend(b: &mut Bencher) {
let ops = create_test_render_ops();
b.iter(|| {
let mut collection = RenderOpsVec::new();
collection.extend(ops.iter().cloned());
test::black_box(collection)
});
}
#[bench]
fn bench_vec_with_capacity_extend(b: &mut Bencher) {
let ops = create_test_render_ops();
b.iter(|| {
let mut collection = RenderOpsVec::with_capacity(ops.len());
collection.extend(ops.iter().cloned());
test::black_box(collection)
});
}
#[bench]
fn bench_smallvec_iterate(b: &mut Bencher) {
let ops = create_test_render_ops();
let mut collection = RenderOpsSmallVec::new();
collection.extend(ops.iter().cloned());
b.iter(|| {
let mut sum = 0;
for op in &collection {
match op {
RenderOp::MoveCursorPositionAbs(pos) => {
sum += pos.row_index.value + pos.col_index.value;
}
RenderOp::MoveCursorPositionRelTo(p1, p2) => {
sum += p1.row_index.value
+ p1.col_index.value
+ p2.row_index.value
+ p2.col_index.value;
}
_ => sum += 1,
}
}
test::black_box(sum)
});
}
#[bench]
fn bench_vec_iterate(b: &mut Bencher) {
let ops = create_test_render_ops();
let mut collection = RenderOpsVec::new();
collection.extend(ops.iter().cloned());
b.iter(|| {
let mut sum = 0;
for op in &collection {
match op {
RenderOp::MoveCursorPositionAbs(pos) => {
sum += pos.row_index.value + pos.col_index.value;
}
RenderOp::MoveCursorPositionRelTo(p1, p2) => {
sum += p1.row_index.value
+ p1.col_index.value
+ p2.row_index.value
+ p2.col_index.value;
}
_ => sum += 1,
}
}
test::black_box(sum)
});
}
#[bench]
fn bench_smallvec_clone(b: &mut Bencher) {
let ops = create_test_render_ops();
let mut collection = RenderOpsSmallVec::new();
collection.extend(ops.iter().cloned());
b.iter(|| test::black_box(collection.clone()));
}
#[bench]
fn bench_vec_clone(b: &mut Bencher) {
let ops = create_test_render_ops();
let mut collection = RenderOpsVec::new();
collection.extend(ops.iter().cloned());
b.iter(|| test::black_box(collection.clone()));
}
#[bench]
fn bench_smallvec_text_line_render(b: &mut Bencher) {
b.iter(|| {
let mut ops = RenderOpsSmallVec::new();
ops.push(RenderOp::MoveCursorPositionAbs(Pos {
row_index: ch(5).into(),
col_index: ch(10).into(),
}));
ops.push(RenderOp::ResetColor);
ops.push(RenderOp::SetFgColor(TuiColor::Rgb(RgbValue::from_u8(
255, 255, 255,
))));
ops.push(RenderOp::SetBgColor(TuiColor::Ansi(AnsiValue::new(232))));
ops.push(RenderOp::PaintTextWithAttributes(
InlineString::from("This is a line of text in the editor"),
None,
));
ops.push(RenderOp::ResetColor);
test::black_box(ops)
});
}
#[bench]
fn bench_vec_text_line_render(b: &mut Bencher) {
b.iter(|| {
let ops = vec![
RenderOp::MoveCursorPositionAbs(Pos {
row_index: ch(5).into(),
col_index: ch(10).into(),
}),
RenderOp::ResetColor,
RenderOp::SetFgColor(TuiColor::Rgb(RgbValue::from_u8(255, 255, 255))),
RenderOp::SetBgColor(TuiColor::Ansi(AnsiValue::new(232))),
RenderOp::PaintTextWithAttributes(
InlineString::from("This is a line of text in the editor"),
None,
),
RenderOp::ResetColor,
];
test::black_box(ops)
});
}
#[bench]
fn bench_vec_with_capacity_text_line_render(b: &mut Bencher) {
b.iter(|| {
let ops = vec![
RenderOp::MoveCursorPositionAbs(Pos {
row_index: ch(5).into(),
col_index: ch(10).into(),
}),
RenderOp::ResetColor,
RenderOp::SetFgColor(TuiColor::Rgb(RgbValue::from_u8(255, 255, 255))),
RenderOp::SetBgColor(TuiColor::Ansi(AnsiValue::new(232))),
RenderOp::PaintTextWithAttributes(
InlineString::from("This is a line of text in the editor"),
None,
),
RenderOp::ResetColor,
];
test::black_box(ops)
});
}
}