Skip to content

Commit

Permalink
Add some benchmarks with unicode characters
Browse files Browse the repository at this point in the history
  • Loading branch information
Yaraslaut committed Mar 25, 2024
1 parent e409050 commit 2df211a
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 51 deletions.
Binary file added benchmark_results.zip
Binary file not shown.
98 changes: 85 additions & 13 deletions libtermbench/termbench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,35 +421,107 @@ std::unique_ptr<Test> binary()
return std::make_unique<Binary>();
}

std::unique_ptr<Test> ascii_line(size_t N)
std::unique_ptr<Test> ascii_line(size_t line_length)
{
auto name = std::to_string(N) + " chars per line";
auto text = std::string(N, 'a') + std::string { "\n" };
auto name = std::to_string(line_length) + " chars per line";
auto text = std::string(line_length, 'a') + std::string { "\n" };
return std::make_unique<Line>(name, text);
}

std::unique_ptr<Test> sgr_line(size_t N)
std::unique_ptr<Test> sgr_line(size_t line_length)
{
auto name = std::to_string(N) + " chars with sgr per line";
auto name = std::to_string(line_length) + " chars with sgr per line";
std::string text {};
text += std::string { "\033[38;2;20;200;200m" };
text += std::string(N, 'a');
text += "\033[38;2;20;200;200m";
text += std::string(line_length, 'a');
text += "\n";
text += "\033[38;2;255;255;255m";
return std::make_unique<Line>(name, text);
}

std::unique_ptr<Test> sgrbg_line(size_t line_length)
{
auto name = std::to_string(line_length) + " chars with sgr and bg per line";
std::string text {};
text += "\033[38;2;20;200;200m\033[48;2;100;100;100m";
text += std::string(line_length, 'a');
text += "\033[38;2;255;255;255m\033[48;2;0;0;0m";
text += "\n";
return std::make_unique<Line>(name, text);
}

std::unique_ptr<Test> unicode_simple(size_t line_length)
{
auto name = std::to_string(line_length) + " unicode simple";
std::string text {};
for (size_t i = 0; i < line_length; ++i)
text += "\u0041";
text += "\n";
return std::make_unique<Line>(name, text);
}

std::unique_ptr<Test> unicode_two_codepoints(size_t line_length)
{
auto name = std::to_string(line_length) + " unicode diacritic";
std::string text {};
for (size_t i = 0; i < line_length; ++i)
text += "\u0041\u0308";
text += "\n";
return std::make_unique<Line>(name, text);
}


std::unique_ptr<Test> unicode_three_codepoints(size_t line_length)
{
auto name = std::to_string(line_length) + " unicode double diacritic";
std::string text {};
for (size_t i = 0; i < static_cast<size_t>(line_length / 2); ++i)
text += "\u0041\u035D\u0042";
text += "\n";
return std::make_unique<Line>(name, text);
}


std::unique_ptr<Test> unicode_fire_as_text(size_t line_length)
{
auto name = std::to_string(line_length) + " unicode fire as text";
std::string text {};
for (size_t i = 0; i < static_cast<size_t>(line_length / 2); ++i)
text += std::string { "\U0001F525\U0000FE0E" };
text += std::string { "\n" };
text += std::string { "\033[38;2;255;255;255m" };
return std::make_unique<Line>(name, text);
}

std::unique_ptr<Test> sgrbg_line(size_t N)

std::unique_ptr<Test> unicode_fire(size_t line_length)
{
auto name = std::to_string(N) + " chars with sgr and bg per line";
auto name = std::to_string(line_length) + " unicode fire";
std::string text {};
text += std::string { "\033[38;2;20;200;200m\033[48;2;100;100;100m" };
text += std::string(N, 'a');
text += std::string { "\033[38;2;255;255;255m\033[48;2;0;0;0m" };
for (size_t i = 0; i < static_cast<size_t>(line_length / 2); ++i)
text += std::string { "\U0001F525" };
text += std::string { "\n" };
return std::make_unique<Line>(name, text);
}

std::unique_ptr<Test> unicode_flag(size_t line_length)
{
auto name = std::to_string(line_length) + " unicode flag";
std::string text {};
std::string flag {};
flag += "\U0001F3F4";
flag += "\U000E0067";
flag += "\U000E0062";
flag += "\U000E0065";
flag += "\U000E006E";
flag += "\U000E0067";
flag += "\U000E007F";

for (size_t i = 0; i < static_cast<size_t>(line_length / 2); ++i)
text += flag;
text += "\n";
return std::make_unique<Line>(name, text);
}

std::unique_ptr<Test> crafted(std::string name, std::string description, std::string text)
{
return std::make_unique<CraftedTest>(std::move(name), std::move(description), std::move(text));
Expand Down
6 changes: 6 additions & 0 deletions libtermbench/termbench.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,11 @@ std::unique_ptr<Test> binary();
std::unique_ptr<Test> ascii_line(size_t);
std::unique_ptr<Test> sgr_line(size_t);
std::unique_ptr<Test> sgrbg_line(size_t);
std::unique_ptr<Test> unicode_simple(size_t);
std::unique_ptr<Test> unicode_two_codepoints(size_t);
std::unique_ptr<Test> unicode_three_codepoints(size_t);
std::unique_ptr<Test> unicode_flag(size_t);
std::unique_ptr<Test> unicode_fire_as_text(size_t); // U+FEOE
std::unique_ptr<Test> unicode_fire(size_t);
std::unique_ptr<Test> crafted(std::string name, std::string description, std::string text);
} // namespace termbench::tests
11 changes: 7 additions & 4 deletions scripts/Xvfb-bench-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ CONTOUR_BIN="${CONTOUR_BIN:-contour}"
KITTY_BIN="${KITTY_BIN:-kitty}"
XTERM_BIN="${XTERM_BIN:-xterm}"
ALACRITTY_BIN="${ALACRITTY_BIN:-alacritty}"
WEZTERM_BIN="${WEZTERM_BIN:-wezterm}"
FB_DISPLAY="${FB_DISPLAY:-:99}"

OUTPUT_DIR="${PWD}"
Expand All @@ -31,6 +32,7 @@ require_bin "${CONTOUR_BIN}"
require_bin "${KITTY_BIN}"
require_bin "${XTERM_BIN}"
require_bin "${ALACRITTY_BIN}"
require_bin "${WEZTERM_BIN}"

export TB_BIN=$(realpath $TB_BIN)
export DISPLAY=${FB_DISPLAY}
Expand All @@ -47,12 +49,12 @@ function program_exit() {
function bench_terminal() {
printf "\033[1m==> Running terminal: $1\033[m\n"
local terminal_name=$(basename $1)
time "${@}" -e "${TB_BIN}" --fixed-size --stdout-fastpath --column-by-column --output "${OUTPUT_DIR}/${terminal_name}_results"
time "${@}" -e "${TB_BIN}" --fixed-size --column-by-column --size 10 --output "${OUTPUT_DIR}/${terminal_name}_results"
local exit_code=$?
printf "\033[1m==> Terminal exit code: $exit_code\033[m\n"
if [[ $exit_code -ne 0 ]]; then
program_exit $exit_code
fi
# if [[ $exit_code -ne 0 ]]; then
# program_exit $exit_code
# fi
}

set -x
Expand All @@ -67,5 +69,6 @@ bench_terminal "${CONTOUR_BIN}" display ${DISPLAY}
bench_terminal "${KITTY_BIN}"
bench_terminal "${XTERM_BIN}" -display ${DISPLAY}
bench_terminal "${ALACRITTY_BIN}"
bench_terminal "${WEZTERM_BIN}"

program_exit 0
61 changes: 44 additions & 17 deletions scripts/plot_results.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,23 @@ end

function get_data(data, data_type)
if data_type == :ascii
name = "chars per line"
name = "chars per line:"
elseif data_type == :sgr
name = "chars with sgr per line"
name = "chars with sgr per line:"
elseif data_type == :sgr_bg
name = "chars with sgr and bg per line"
name = "chars with sgr and bg per line:"
elseif data_type == :unicode
name = "unicode simple:"
elseif data_type == :diacritic
name = "unicode diacritic:"
elseif data_type == :diacritic_double
name = "unicode double diacritic:"
elseif data_type == :fire
name = "unicode fire:"
elseif data_type == :fire_text
name = "unicode fire as text:"
elseif data_type == :flag
name = "unicode flag:"
end

lines = []
Expand All @@ -38,7 +50,8 @@ end



function generate_for_terminal(file_name)
function generate_for_terminal(file_name, prefix="results_")
try
terminal_name = split(file_name,"_")[1]

fig = Figure()
Expand All @@ -47,39 +60,53 @@ function generate_for_terminal(file_name)
data = split(open(io->read(io, String), file_name), '\n')
terminal_name = split(file_name,"_")[1]

markers = [:circle :rect :cross :star4 :start5 :star6 :diamond]

get_data_l = (type) -> get_data(data,type)
ascii_speed = get_data_l(:ascii)
sgr_speed = get_data_l(:sgr)
sgr_bg_speed = get_data_l(:sgr_bg)
speed = [ get_data_l(t) for t in types]

marker_size = 8
scatter!(ax,ascii_speed, label= terminal_name * "_ascii", marker = :circle, markersize = marker_size)
scatter!(ax,sgr_speed, label=terminal_name*"_sgr", marker = :rect, markersize = marker_size)
scatter!(ax,sgr_bg_speed, label=terminal_name*"_sgr_and_bg", marker = :cross, markersize = marker_size)
for (ind,dat) in enumerate(speed)
scatter!(ax,dat, label= terminal_name * "_" * string(types[ind]), marker = markers[ind], markersize = marker_size)
end
axislegend(position = :rt)

save("results_"*terminal_name*".png", fig)
save(prefix*terminal_name*".png", fig)
catch e
println(e)
end
end

function generate_comparison(type)
try
fig = Figure()
ax = Axis(fig[1,1], title = "Comparison for "*string(type), xlabel = "Length of line", ylabel = "throughput, MB/s")

insert_from_data(ax,"contour_results",:circle, type)
insert_from_data(ax,"alacritty_results",:rect, type)
insert_from_data(ax,"xterm_results",:cross, type)
insert_from_data(ax,"kitty_results",:utriangle, type)
insert_from_data(ax,"wezterm_results",:diamond, type)
axislegend(position = :lt)
return fig
catch e
println(e)
end
end


types = [:ascii :sgr :sgr_bg ]
generate_for_terminal("contour_results")
generate_for_terminal("alacritty_results")
generate_for_terminal("xterm_results")
generate_for_terminal("kitty_results")


save("comparison_ascii.png", generate_comparison(:ascii))
save("comparison_sgr.png", generate_comparison(:sgr))
save("comparison_sgr_bg.png", generate_comparison(:sgr_bg))
generate_for_terminal("wezterm_results")
types = [:unicode :fire :flag :diacritic :diacritic_double :fire_text]
generate_for_terminal_l = (n) -> generate_for_terminal(n, "results_unicode_")
generate_for_terminal_l("contour_results")
generate_for_terminal_l("alacritty_results")
generate_for_terminal_l("xterm_results")
generate_for_terminal_l("kitty_results")
generate_for_terminal_l("wezterm_results")

types = [:ascii :sgr :sgr_bg :unicode :fire :fire_text :flag :diacritic :diacritic_double]
[ save("comparison_"*string(type)*".png", generate_comparison(type)) for type in types ]
62 changes: 45 additions & 17 deletions tb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,26 @@ void chunkedWriteToStdout(char const* _data, size_t _size)
#endif
}

struct TestsToRun
{
bool manyLines { true };
bool longLines { true };
bool sgrLines { true };
bool sgrFgBgLines { true };
bool binary { true };
bool columnByColumn { false };
};

struct BenchSettings
{
TerminalSize requestedTerminalSize {};
size_t testSizeMB = 32;
bool nullSink = false;
bool stdoutFastPath = false;
std::vector<std::filesystem::path> craftedTests {};
bool columnByColumn = false;
std::string fileout {};
std::optional<int> earlyExitCode = std::nullopt;
TestsToRun tests {};
};

BenchSettings parseArguments(int argc, char const* argv[], TerminalSize const& initialTerminalSize)
Expand All @@ -133,7 +143,7 @@ BenchSettings parseArguments(int argc, char const* argv[], TerminalSize const& i
}
else if (argv[i] == "--fixed-size"sv)
{
settings.requestedTerminalSize.columns = 200;
settings.requestedTerminalSize.columns = 100;
settings.requestedTerminalSize.lines = 30;
}
else if (argv[i] == "--stdout-fastpath"sv)
Expand All @@ -148,7 +158,12 @@ BenchSettings parseArguments(int argc, char const* argv[], TerminalSize const& i
else if (argv[i] == "--column-by-column"sv)
{
cout << std::format("Enabling column-by-column tests.\n");
settings.columnByColumn = true;
settings.tests.columnByColumn = true;
settings.tests.manyLines = false;
settings.tests.longLines = false;
settings.tests.sgrLines = false;
settings.tests.sgrFgBgLines = false;
settings.tests.binary = false;
}
else if (argv[i] == "--size"sv && i + 1 < argc)
{
Expand Down Expand Up @@ -201,12 +216,17 @@ std::string loadFileContents(std::filesystem::path const& path)

bool addTestsToBenchmark(termbench::Benchmark& tb, BenchSettings const& settings)
{
tb.add(termbench::tests::many_lines());
tb.add(termbench::tests::long_lines());
tb.add(termbench::tests::sgr_fg_lines());
tb.add(termbench::tests::sgr_fgbg_lines());
tb.add(termbench::tests::binary());
// TODO: The above tests should also be configurable via command line (-mlfgb).

if (settings.tests.manyLines)
tb.add(termbench::tests::many_lines());
if (settings.tests.longLines)
tb.add(termbench::tests::long_lines());
if (settings.tests.sgrLines)
tb.add(termbench::tests::sgr_fg_lines());
if (settings.tests.sgrFgBgLines)
tb.add(termbench::tests::sgr_fgbg_lines());
if (settings.tests.binary)
tb.add(termbench::tests::binary());

for (auto const& test: settings.craftedTests)
{
Expand All @@ -219,17 +239,25 @@ bool addTestsToBenchmark(termbench::Benchmark& tb, BenchSettings const& settings
tb.add(termbench::tests::crafted(test.filename().string(), "", std::move(content)));
}

if (settings.columnByColumn)
if (settings.tests.columnByColumn)
{
auto const maxColumns { settings.requestedTerminalSize.columns * 2u };
for (size_t i = 0; i < maxColumns; ++i)
tb.add(termbench::tests::ascii_line(i));
for (size_t i = 0; i < maxColumns; ++i)
tb.add(termbench::tests::sgr_line(i));
for (size_t i = 0; i < maxColumns; ++i)
tb.add(termbench::tests::sgrbg_line(i));
}

auto add_test = [&](auto&& test) {
for (size_t i = 0; i < maxColumns; ++i)
tb.add(std::invoke(test,i));
};

add_test(termbench::tests::ascii_line);
add_test(termbench::tests::unicode_simple);
add_test(termbench::tests::unicode_two_codepoints);
add_test(termbench::tests::unicode_three_codepoints);
add_test(termbench::tests::unicode_fire_as_text);
add_test(termbench::tests::unicode_fire);
add_test(termbench::tests::unicode_flag);
add_test(termbench::tests::sgr_line);
add_test(termbench::tests::sgrbg_line);
}
return true;
}

Expand Down

0 comments on commit 2df211a

Please sign in to comment.