Skip to content

Commit

Permalink
Merge pull request #17 from contour-terminal/improvement/unicode_bench
Browse files Browse the repository at this point in the history
Add some benchmarks with unicode characters
  • Loading branch information
christianparpart authored Apr 1, 2024
2 parents e409050 + 9e32854 commit 679b3cc
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 63 deletions.
20 changes: 8 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
sudo apt-get install clang-format-17
- name: "Clang-format libtermbench"
run: find ./libtermbench -name "*.cpp" -o -name "*.h" | xargs clang-format-17 --Werror --dry-run
- name: "Clang-format tb1"
- name: "Clang-format tb"
run: find ./tb -name "*.cpp" -o -name "*.h" | xargs clang-format-17 --Werror --dry-run
- name: "Check includes"
run: ./scripts/check-includes.sh
Expand Down Expand Up @@ -93,18 +93,14 @@ jobs:
run: cargo install alacritty
- name: "Install kitty and xterm"
run: sudo apt install -y kitty xterm xvfb
- name: "run benchmarks"
- name: "Install wezterm"
run: |
curl -fsSL https://apt.fury.io/wez/gpg.key | sudo gpg --yes --dearmor -o /usr/share/keyrings/wezterm-fury.gpg
echo 'deb [signed-by=/usr/share/keyrings/wezterm-fury.gpg] https://apt.fury.io/wez/ * *' | sudo tee /etc/apt/sources.list.d/wezterm.list
sudo apt update
sudo apt install wezterm
- name: "Run benchmarks"
run: ./scripts/Xvfb-bench-run.sh "./build/$CMAKE_PRESET/tb/tb"
- name: "ls"
run: ls -la
- name: "cat contour_results"
run: cat contour_results
- name: "cat kitty_results"
run: cat kitty_results
- name: "cat xterm_results"
run: cat xterm_results
- name: "cat alacritty_results"
run: cat alacritty_results
- name: "Set up Julia"
uses: julia-actions/setup-julia@v1
- name: "Create Plots"
Expand Down
95 changes: 82 additions & 13 deletions libtermbench/termbench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,35 +421,104 @@ 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 += "\u0061";
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 += "\u0061\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 += "\u0061\u035D\u0062";
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
8 changes: 4 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,9 @@ 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 2 --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
}

set -x
Expand All @@ -67,5 +66,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 ]
Loading

0 comments on commit 679b3cc

Please sign in to comment.