From a4e6f1a09b749935707e220139c2bc3c2ac6b519 Mon Sep 17 00:00:00 2001 From: Yaraslau Tamashevich Date: Fri, 15 Mar 2024 19:45:03 +0200 Subject: [PATCH] Update of termbench with scripts to create plots --- .clang-format | 81 +++++++ .github/workflows/build.yml | 79 ++----- CMakeLists.txt | 3 - alacritty_results | 72 ++++++ kitty_results | 72 ++++++ libtermbench/CMakeLists.txt | 1 - libtermbench/termbench.cpp | 436 ++++++++++++++++++++---------------- libtermbench/termbench.h | 54 +++-- scripts/Xvfb-bench-run.sh | 22 ++ scripts/check-includes.sh | 14 ++ scripts/install-deps.sh | 9 - scripts/plot_results.jl | 92 ++++++++ tb/CMakeLists.txt | 2 +- tb/main.cpp | 142 +++++++----- xterm_results | 72 ++++++ 15 files changed, 796 insertions(+), 355 deletions(-) create mode 100644 .clang-format create mode 100644 alacritty_results create mode 100644 kitty_results create mode 100644 scripts/Xvfb-bench-run.sh create mode 100755 scripts/check-includes.sh create mode 100644 scripts/plot_results.jl create mode 100644 xterm_results diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..5edcb6b --- /dev/null +++ b/.clang-format @@ -0,0 +1,81 @@ +--- +BasedOnStyle: Microsoft +AccessModifierOffset: '-2' +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: 'true' +AlignConsecutiveDeclarations: 'false' +AlignEscapedNewlines: Left +AlignOperands: 'true' +AlignTrailingComments: 'true' +AllowAllArgumentsOnNextLine: 'true' +AllowAllConstructorInitializersOnNextLine: 'true' +AllowAllParametersOfDeclarationOnNextLine: 'true' +AllowShortBlocksOnASingleLine: 'false' +AllowShortCaseLabelsOnASingleLine: 'true' +AllowShortFunctionsOnASingleLine: InlineOnly +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: Inline +AllowShortLoopsOnASingleLine: 'false' +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: 'false' +AlwaysBreakTemplateDeclarations: 'Yes' +BinPackArguments: 'false' +BinPackParameters: 'false' +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: 'true' +BreakConstructorInitializers: AfterColon +BreakInheritanceList: AfterColon +BreakStringLiterals: 'true' +ColumnLimit: '110' +CompactNamespaces: 'false' +ConstructorInitializerAllOnOneLineOrOnePerLine: 'true' +ConstructorInitializerIndentWidth: '4' +ContinuationIndentWidth: '4' +Cpp11BracedListStyle: 'false' +DerivePointerAlignment: 'false' +FixNamespaceComments: 'true' +IncludeBlocks: Regroup +IndentCaseLabels: true +IndentPPDirectives: BeforeHash +IndentWidth: '4' +IndentWrappedFunctionNames: 'false' +Language: Cpp +MaxEmptyLinesToKeep: '1' +NamespaceIndentation: Inner +PenaltyBreakAssignment: '0' +PointerAlignment: Left +ReflowComments: 'true' +SortIncludes: 'true' +SortUsingDeclarations: 'true' +SpaceAfterCStyleCast: 'true' +SpaceAfterLogicalNot: 'false' +SpaceAfterTemplateKeyword: 'true' +SpaceBeforeAssignmentOperators: 'true' +SpaceBeforeCpp11BracedList: 'true' +SpaceBeforeCtorInitializerColon: 'false' +SpaceBeforeInheritanceColon: 'false' +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: 'false' +SpaceInEmptyParentheses: 'false' +SpacesInAngles: 'false' +SpacesInCStyleCastParentheses: 'false' +SpacesInContainerLiterals: 'false' +SpacesInParentheses: 'false' +SpacesInSquareBrackets: 'false' +Standard: Cpp11 +TabWidth: '4' +UseTab: Never +IncludeCategories: + - Regex: '^<(tb)/' + Priority: 0 + - Regex: '^<(libtermbench)/' + Priority: 1 + - Regex: '^' + Priority: 81 + - Regex: '<[[:alnum:]_]+\.h>' + Priority: 82 + - Regex: '.*' + Priority: 99 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 428b1b7..3595690 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,6 +23,26 @@ env: CTEST_OUTPUT_ON_FAILURE: 1 jobs: + + + check_clang_format: + name: "Check C++ style" + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - name: Install clang + run: | + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 17 + 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" + run: find ./tb -name "*.cpp" -o -name "*.h" | xargs clang-format-17 --Werror --dry-run + - name: "Check includes" + run: ./scripts/check-includes.sh + ubuntu_linux: name: "Ubuntu Linux 22.04" runs-on: ubuntu-22.04 @@ -43,62 +63,11 @@ jobs: set -ex sudo apt -q update sudo ./scripts/install-deps.sh + - name: "Install GCC 13" + run: sudo apt install g++-13 - name: "cmake" run: cmake -S . -B build -DCMAKE_BUILD_TYPE="RelWithDebInfo" - name: "build" run: cmake --build build/ -- -j3 - - osx: - name: "OS/X" - runs-on: macos-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 - with: - path: "**/cpm_modules" - key: ${{github.workflow}}-cpm-modules-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }} - - name: set variables - id: set_vars - run: ./scripts/ci-set-vars.sh - env: - REPOSITORY: ${{ github.event.repository.name }} - - name: "Install dependencies" - run: | - set -ex - #brew update - ./scripts/install-deps.sh - - name: "Create build directory" - run: mkdir build - - name: "Generate build files" - run: cmake -S . -B build -DCMAKE_BUILD_TYPE="RelWithDebInfo" - - name: "Build" - run: cmake --build build/ - - windows: - name: "Windows" - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - name: setup environment - shell: powershell - id: set_vars - run: .\scripts\ci-set-vars.ps1 - env: - REPOSITORY: ${{ github.event.repository.name }} - - name: "vcpkg: Install dependencies" - uses: lukka/run-vcpkg@v11.1 - id: runvcpkg - with: - vcpkgDirectory: ${{ runner.workspace }}/vcpkg/ - vcpkgGitCommitId: 3e93bb69a1cadeb36fe9eca3b6f3912d84f618d5 - - name: "create build directory" - shell: powershell - run: | - If (!(Test-Path build)) - { - New-Item -ItemType Directory -Force -Path build - } - - name: "Generate build files" - run: cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="${{ runner.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows -B build . - - name: "Build" - run: cmake --build build/ --config Release + - name: "run benchmarks" + run: ./scripts/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b40f21..4bf145c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,9 +28,6 @@ if(DEFINED MSVC) add_definitions(-D_USE_MATH_DEFINES) endif() -if(NOT TARGET fmt) - find_package(fmt REQUIRED) -endif() add_subdirectory(libtermbench) add_subdirectory(tb) diff --git a/alacritty_results b/alacritty_results new file mode 100644 index 0000000..6d89b46 --- /dev/null +++ b/alacritty_results @@ -0,0 +1,72 @@ +All 65 tests finished. +--------------------- + + many_lines: 0.0390 seconds, 82.051 MB/s (normalized: 48.623 KB/s) + long_lines: 0.0310 seconds, 103.226 MB/s (normalized: 61.171 KB/s) + sgr_fg_lines: 0.0182 seconds, 175.824 MB/s (normalized: 104.192 KB/s) + sgr_fg_bg_lines: 0.0189 seconds, 169.312 MB/s (normalized: 100.333 KB/s) + binary: 0.0387 seconds, 82.687 MB/s (normalized: 49.000 KB/s) + 0 chars per line: 4.0861 seconds, 6.583 MB/s (normalized: 3.901 KB/s) + 1 chars per line: 3.0264 seconds, 9.804 MB/s (normalized: 5.810 KB/s) + 2 chars per line: 2.0195 seconds, 14.579 MB/s (normalized: 8.639 KB/s) + 3 chars per line: 1.0657 seconds, 19.312 MB/s (normalized: 11.444 KB/s) + 4 chars per line: 1.0338 seconds, 23.916 MB/s (normalized: 14.173 KB/s) + 5 chars per line: 1.0134 seconds, 28.219 MB/s (normalized: 16.722 KB/s) + 6 chars per line: 0.0963 seconds, 33.229 MB/s (normalized: 19.692 KB/s) + 7 chars per line: 0.0852 seconds, 37.559 MB/s (normalized: 22.257 KB/s) + 8 chars per line: 0.0768 seconds, 41.667 MB/s (normalized: 24.691 KB/s) + 9 chars per line: 0.0696 seconds, 45.977 MB/s (normalized: 27.246 KB/s) + 10 chars per line: 0.0653 seconds, 49.005 MB/s (normalized: 29.040 KB/s) + 11 chars per line: 0.0596 seconds, 53.691 MB/s (normalized: 31.817 KB/s) + 12 chars per line: 0.0549 seconds, 58.288 MB/s (normalized: 34.541 KB/s) + 13 chars per line: 0.0512 seconds, 62.500 MB/s (normalized: 37.037 KB/s) + 14 chars per line: 0.0494 seconds, 64.777 MB/s (normalized: 38.387 KB/s) + 15 chars per line: 0.0472 seconds, 67.797 MB/s (normalized: 40.176 KB/s) + 16 chars per line: 0.0455 seconds, 70.330 MB/s (normalized: 41.677 KB/s) + 17 chars per line: 0.0450 seconds, 71.111 MB/s (normalized: 42.140 KB/s) + 18 chars per line: 0.0432 seconds, 74.074 MB/s (normalized: 43.896 KB/s) + 19 chars per line: 0.0422 seconds, 75.829 MB/s (normalized: 44.936 KB/s) + 0 chars with sgr per line: 0.0284 seconds, 112.676 MB/s (normalized: 66.771 KB/s) + 1 chars with sgr per line: 0.0296 seconds, 108.108 MB/s (normalized: 64.064 KB/s) + 2 chars with sgr per line: 0.0289 seconds, 110.727 MB/s (normalized: 65.616 KB/s) + 3 chars with sgr per line: 0.0286 seconds, 111.888 MB/s (normalized: 66.304 KB/s) + 4 chars with sgr per line: 0.0275 seconds, 116.364 MB/s (normalized: 68.956 KB/s) + 5 chars with sgr per line: 0.0274 seconds, 116.788 MB/s (normalized: 69.208 KB/s) + 6 chars with sgr per line: 0.0274 seconds, 116.788 MB/s (normalized: 69.208 KB/s) + 7 chars with sgr per line: 0.0279 seconds, 114.695 MB/s (normalized: 67.968 KB/s) + 8 chars with sgr per line: 0.0285 seconds, 112.281 MB/s (normalized: 66.537 KB/s) + 9 chars with sgr per line: 0.0276 seconds, 115.942 MB/s (normalized: 68.706 KB/s) + 10 chars with sgr per line: 0.0290 seconds, 110.345 MB/s (normalized: 65.390 KB/s) + 11 chars with sgr per line: 0.0265 seconds, 120.755 MB/s (normalized: 71.558 KB/s) + 12 chars with sgr per line: 0.0272 seconds, 117.647 MB/s (normalized: 69.717 KB/s) + 13 chars with sgr per line: 0.0268 seconds, 119.403 MB/s (normalized: 70.757 KB/s) + 14 chars with sgr per line: 0.0277 seconds, 115.523 MB/s (normalized: 68.458 KB/s) + 15 chars with sgr per line: 0.0290 seconds, 110.345 MB/s (normalized: 65.390 KB/s) + 16 chars with sgr per line: 0.0276 seconds, 115.942 MB/s (normalized: 68.706 KB/s) + 17 chars with sgr per line: 0.0269 seconds, 118.959 MB/s (normalized: 70.494 KB/s) + 18 chars with sgr per line: 0.0244 seconds, 131.148 MB/s (normalized: 77.717 KB/s) + 19 chars with sgr per line: 0.0261 seconds, 122.605 MB/s (normalized: 72.655 KB/s) + 0 chars with sgr and bg per line: 0.0246 seconds, 130.081 MB/s (normalized: 77.085 KB/s) + 1 chars with sgr and bg per line: 0.0252 seconds, 126.984 MB/s (normalized: 75.250 KB/s) + 2 chars with sgr and bg per line: 0.0260 seconds, 123.077 MB/s (normalized: 72.934 KB/s) + 3 chars with sgr and bg per line: 0.0255 seconds, 125.490 MB/s (normalized: 74.365 KB/s) + 4 chars with sgr and bg per line: 0.0214 seconds, 149.533 MB/s (normalized: 88.612 KB/s) + 5 chars with sgr and bg per line: 0.0228 seconds, 140.351 MB/s (normalized: 83.171 KB/s) + 6 chars with sgr and bg per line: 0.0272 seconds, 117.647 MB/s (normalized: 69.717 KB/s) + 7 chars with sgr and bg per line: 0.0254 seconds, 125.984 MB/s (normalized: 74.657 KB/s) + 8 chars with sgr and bg per line: 0.0242 seconds, 132.231 MB/s (normalized: 78.359 KB/s) + 9 chars with sgr and bg per line: 0.0223 seconds, 143.498 MB/s (normalized: 85.036 KB/s) + 10 chars with sgr and bg per line: 0.0221 seconds, 144.796 MB/s (normalized: 85.805 KB/s) + 11 chars with sgr and bg per line: 0.0224 seconds, 142.857 MB/s (normalized: 84.656 KB/s) + 12 chars with sgr and bg per line: 0.0267 seconds, 119.850 MB/s (normalized: 71.022 KB/s) + 13 chars with sgr and bg per line: 0.0249 seconds, 128.514 MB/s (normalized: 76.156 KB/s) + 14 chars with sgr and bg per line: 0.0232 seconds, 137.931 MB/s (normalized: 81.737 KB/s) + 15 chars with sgr and bg per line: 0.0218 seconds, 146.789 MB/s (normalized: 86.986 KB/s) + 16 chars with sgr and bg per line: 0.0243 seconds, 131.687 MB/s (normalized: 78.037 KB/s) + 17 chars with sgr and bg per line: 0.0238 seconds, 134.454 MB/s (normalized: 79.676 KB/s) + 18 chars with sgr and bg per line: 0.0236 seconds, 135.593 MB/s (normalized: 80.352 KB/s) + 19 chars with sgr and bg per line: 0.0225 seconds, 142.222 MB/s (normalized: 84.280 KB/s) + all tests: 34.0550 seconds, 60.203 MB/s (normalized: 35.676 KB/s) + + screen size: 72x24 + data size: 32.000 MB diff --git a/kitty_results b/kitty_results new file mode 100644 index 0000000..b631ccd --- /dev/null +++ b/kitty_results @@ -0,0 +1,72 @@ +All 65 tests finished. +--------------------- + + many_lines: 0.0547 seconds, 58.501 MB/s (normalized: 42.187 KB/s) + long_lines: 0.0490 seconds, 65.306 MB/s (normalized: 47.094 KB/s) + sgr_fg_lines: 0.0492 seconds, 65.041 MB/s (normalized: 46.903 KB/s) + sgr_fg_bg_lines: 0.0489 seconds, 65.440 MB/s (normalized: 47.190 KB/s) + binary: 0.0552 seconds, 57.971 MB/s (normalized: 41.804 KB/s) + 0 chars per line: 5.0859 seconds, 5.462 MB/s (normalized: 3.939 KB/s) + 1 chars per line: 3.0544 seconds, 9.029 MB/s (normalized: 6.511 KB/s) + 2 chars per line: 2.0494 seconds, 12.831 MB/s (normalized: 9.253 KB/s) + 3 chars per line: 1.0836 seconds, 17.429 MB/s (normalized: 12.569 KB/s) + 4 chars per line: 1.0449 seconds, 22.084 MB/s (normalized: 15.926 KB/s) + 5 chars per line: 1.0248 seconds, 25.641 MB/s (normalized: 18.490 KB/s) + 6 chars per line: 1.0063 seconds, 30.103 MB/s (normalized: 21.708 KB/s) + 7 chars per line: 0.0960 seconds, 33.333 MB/s (normalized: 24.038 KB/s) + 8 chars per line: 0.0837 seconds, 38.232 MB/s (normalized: 27.570 KB/s) + 9 chars per line: 0.0801 seconds, 39.950 MB/s (normalized: 28.809 KB/s) + 10 chars per line: 0.0719 seconds, 44.506 MB/s (normalized: 32.095 KB/s) + 11 chars per line: 0.0665 seconds, 48.120 MB/s (normalized: 34.701 KB/s) + 12 chars per line: 0.0638 seconds, 50.157 MB/s (normalized: 36.169 KB/s) + 13 chars per line: 0.0618 seconds, 51.780 MB/s (normalized: 37.340 KB/s) + 14 chars per line: 0.0601 seconds, 53.245 MB/s (normalized: 38.396 KB/s) + 15 chars per line: 0.0574 seconds, 55.749 MB/s (normalized: 40.202 KB/s) + 16 chars per line: 0.0565 seconds, 56.637 MB/s (normalized: 40.843 KB/s) + 17 chars per line: 0.0565 seconds, 56.637 MB/s (normalized: 40.843 KB/s) + 18 chars per line: 0.0581 seconds, 55.077 MB/s (normalized: 39.718 KB/s) + 19 chars per line: 0.0565 seconds, 56.637 MB/s (normalized: 40.843 KB/s) + 0 chars with sgr per line: 0.0543 seconds, 58.932 MB/s (normalized: 42.497 KB/s) + 1 chars with sgr per line: 0.0542 seconds, 59.041 MB/s (normalized: 42.576 KB/s) + 2 chars with sgr per line: 0.0541 seconds, 59.150 MB/s (normalized: 42.654 KB/s) + 3 chars with sgr per line: 0.0535 seconds, 59.813 MB/s (normalized: 43.133 KB/s) + 4 chars with sgr per line: 0.0541 seconds, 59.150 MB/s (normalized: 42.654 KB/s) + 5 chars with sgr per line: 0.0541 seconds, 59.150 MB/s (normalized: 42.654 KB/s) + 6 chars with sgr per line: 0.0540 seconds, 59.259 MB/s (normalized: 42.733 KB/s) + 7 chars with sgr per line: 0.0532 seconds, 60.150 MB/s (normalized: 43.376 KB/s) + 8 chars with sgr per line: 0.0540 seconds, 59.259 MB/s (normalized: 42.733 KB/s) + 9 chars with sgr per line: 0.0541 seconds, 59.150 MB/s (normalized: 42.654 KB/s) + 10 chars with sgr per line: 0.0536 seconds, 59.701 MB/s (normalized: 43.052 KB/s) + 11 chars with sgr per line: 0.0539 seconds, 59.369 MB/s (normalized: 42.813 KB/s) + 12 chars with sgr per line: 0.0533 seconds, 60.038 MB/s (normalized: 43.295 KB/s) + 13 chars with sgr per line: 0.0541 seconds, 59.150 MB/s (normalized: 42.654 KB/s) + 14 chars with sgr per line: 0.0531 seconds, 60.264 MB/s (normalized: 43.458 KB/s) + 15 chars with sgr per line: 0.0541 seconds, 59.150 MB/s (normalized: 42.654 KB/s) + 16 chars with sgr per line: 0.0539 seconds, 59.369 MB/s (normalized: 42.813 KB/s) + 17 chars with sgr per line: 0.0532 seconds, 60.150 MB/s (normalized: 43.376 KB/s) + 18 chars with sgr per line: 0.0541 seconds, 59.150 MB/s (normalized: 42.654 KB/s) + 19 chars with sgr per line: 0.0530 seconds, 60.377 MB/s (normalized: 43.540 KB/s) + 0 chars with sgr and bg per line: 0.0540 seconds, 59.259 MB/s (normalized: 42.733 KB/s) + 1 chars with sgr and bg per line: 0.0531 seconds, 60.264 MB/s (normalized: 43.458 KB/s) + 2 chars with sgr and bg per line: 0.0537 seconds, 59.590 MB/s (normalized: 42.972 KB/s) + 3 chars with sgr and bg per line: 0.0529 seconds, 60.491 MB/s (normalized: 43.622 KB/s) + 4 chars with sgr and bg per line: 0.0541 seconds, 59.150 MB/s (normalized: 42.654 KB/s) + 5 chars with sgr and bg per line: 0.0530 seconds, 60.377 MB/s (normalized: 43.540 KB/s) + 6 chars with sgr and bg per line: 0.0537 seconds, 59.590 MB/s (normalized: 42.972 KB/s) + 7 chars with sgr and bg per line: 0.0528 seconds, 60.606 MB/s (normalized: 43.705 KB/s) + 8 chars with sgr and bg per line: 0.0531 seconds, 60.264 MB/s (normalized: 43.458 KB/s) + 9 chars with sgr and bg per line: 0.0535 seconds, 59.813 MB/s (normalized: 43.133 KB/s) + 10 chars with sgr and bg per line: 0.0526 seconds, 60.837 MB/s (normalized: 43.871 KB/s) + 11 chars with sgr and bg per line: 0.0539 seconds, 59.369 MB/s (normalized: 42.813 KB/s) + 12 chars with sgr and bg per line: 0.0528 seconds, 60.606 MB/s (normalized: 43.705 KB/s) + 13 chars with sgr and bg per line: 0.0527 seconds, 60.721 MB/s (normalized: 43.788 KB/s) + 14 chars with sgr and bg per line: 0.0539 seconds, 59.369 MB/s (normalized: 42.813 KB/s) + 15 chars with sgr and bg per line: 0.0526 seconds, 60.837 MB/s (normalized: 43.871 KB/s) + 16 chars with sgr and bg per line: 0.0538 seconds, 59.480 MB/s (normalized: 42.892 KB/s) + 17 chars with sgr and bg per line: 0.0528 seconds, 60.606 MB/s (normalized: 43.705 KB/s) + 18 chars with sgr and bg per line: 0.0535 seconds, 59.813 MB/s (normalized: 43.133 KB/s) + 19 chars with sgr and bg per line: 0.0528 seconds, 60.606 MB/s (normalized: 43.705 KB/s) + all tests: 50.0164 seconds, 41.464 MB/s (normalized: 29.901 KB/s) + + screen size: 71x20 + data size: 32.000 MB diff --git a/libtermbench/CMakeLists.txt b/libtermbench/CMakeLists.txt index 64caf4b..f34c81e 100644 --- a/libtermbench/CMakeLists.txt +++ b/libtermbench/CMakeLists.txt @@ -22,7 +22,6 @@ set_target_properties(termbench PROPERTIES VERSION "${PROJECT_VERSION}" SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}" ) -target_link_libraries(termbench PUBLIC fmt::fmt-header-only) target_include_directories(termbench PUBLIC $ $) diff --git a/libtermbench/termbench.cpp b/libtermbench/termbench.cpp index 5455f45..f8f37c2 100644 --- a/libtermbench/termbench.cpp +++ b/libtermbench/termbench.cpp @@ -14,14 +14,12 @@ #include "termbench.h" #include +#include +#include #include #include #include -#include - -#include - using std::function; using std::make_unique; using std::min; @@ -38,15 +36,15 @@ namespace { std::string sizeStr(double _value) { - if ((long double)(_value) >= (1024ull * 1024ull * 1024ull)) // GB - return fmt::format("{:7.3f} GB", _value / 1024.0 / 1024.0 / 1024.0); + if ((long double) (_value) >= (1024ull * 1024ull * 1024ull)) // GB + return std::format("{:7.3f} GB", _value / 1024.0 / 1024.0 / 1024.0); if (_value >= (1024 * 1024)) // MB - return fmt::format("{:7.3f} MB", _value / 1024.0 / 1024.0); + return std::format("{:7.3f} MB", _value / 1024.0 / 1024.0); if (_value >= 1024) // KB - return fmt::format("{:7.3f} KB", _value / 1024.0); - return fmt::format("{:7.3f} bytes", _value); + return std::format("{:7.3f} KB", _value / 1024.0); + return std::format("{:7.3f} bytes", _value); } -} +} // namespace using u16 = unsigned short; @@ -55,11 +53,11 @@ Benchmark::Benchmark(function _writer, unsigned short _width, unsigned short _height, function _beforeTest): - writer_{std::move(_writer)}, - beforeTest_{std::move(_beforeTest)}, - testSizeMB_{_testSizeMB}, - width_{_width}, - height_{_height} + writer_ { std::move(_writer) }, + beforeTest_ { std::move(_beforeTest) }, + testSizeMB_ { _testSizeMB }, + width_ { _width }, + height_ { _height } { } @@ -92,7 +90,7 @@ void Benchmark::runAll() } auto const diff = duration_cast(steady_clock::now() - beginTime); - results_.emplace_back(Result{*test, diff, totalSizeBytes}); + results_.emplace_back(Result { *test, diff, totalSizeBytes }); buffer->clear(); test->teardown(*buffer); @@ -103,14 +101,14 @@ void Benchmark::runAll() buffer->clear(); } } - +// void Benchmark::summarize(std::ostream& os) { - os << fmt::format("All {} tests finished.\n", results_.size()); - os << fmt::format("---------------------\n\n"); + os << std::format("All {} tests finished.\n", results_.size()); + os << std::format("---------------------\n\n"); auto const gridCellCount = width_ * height_; - std::chrono::milliseconds totalTime{}; + std::chrono::milliseconds totalTime {}; size_t totalBytes = 0; for (auto const& result: results_) { @@ -118,31 +116,27 @@ void Benchmark::summarize(std::ostream& os) auto const bps = double(result.bytesWritten) / (double(result.time.count()) / 1000.0); totalBytes += result.bytesWritten; totalTime += result.time; - os << fmt::format( - "{:>20}: {:>3}.{:04} seconds, {}/s (normalized: {}/s)\n", - test.name, - result.time.count() / 1000, - result.time.count() % 1000, - sizeStr(bps), - sizeStr(bps / static_cast(gridCellCount)) - ); + os << std::format("{:>40}: {:>3}.{:04} seconds, {}/s (normalized: {}/s)\n", + test.name, + result.time.count() / 1000, + result.time.count() % 1000, + sizeStr(bps), + sizeStr(bps / static_cast(gridCellCount))); } auto const bps = double(totalBytes) / (double(totalTime.count()) / 1000.0); - os << fmt::format( - "{:>20}: {:>3}.{:04} seconds, {}/s (normalized: {}/s)\n", - "all tests", - totalTime.count() / 1000, - totalTime.count() % 1000, - sizeStr(bps), - sizeStr(bps / static_cast(gridCellCount)) - ); + os << std::format("{:>40}: {:>3}.{:04} seconds, {}/s (normalized: {}/s)\n", + "all tests", + totalTime.count() / 1000, + totalTime.count() % 1000, + sizeStr(bps), + sizeStr(bps / static_cast(gridCellCount))); os << "\n"; - os << fmt::format(" screen size: {}x{}\n", width_, height_); - os << fmt::format(" data size: {}\n", sizeStr(static_cast(testSizeMB_ * 1024 * 1024))); + os << std::format(" screen size: {}x{}\n", width_, height_); + os << std::format(" data size: {}\n", sizeStr(static_cast(testSizeMB_ * 1024 * 1024))); } -} +} // namespace contour::termbench namespace contour::termbench::tests { @@ -150,216 +144,231 @@ namespace contour::termbench::tests namespace { -static char randomAsciiChar() -{ - auto constexpr Min = 'a'; // 0x20; - auto constexpr Max = 'z'; // 0x7E; - return static_cast(Min + rand() % (Max - Min + 1)); -} - -void writeChar(Buffer& _sink, char ch) -{ - _sink.write(std::string_view{&ch, 1}); -} - -void writeNumber(Buffer& _sink, unsigned _value) -{ - unsigned remains = _value; - for (unsigned divisor = 1000000000; divisor != 0; divisor /= 10) + static char randomAsciiChar() { - auto const digit = remains / divisor; - remains -= digit * divisor; - - if (digit || (_value != remains) || (divisor == 1)) - writeChar(_sink, static_cast('0' + digit)); + auto constexpr Min = 'a'; // 0x20; + auto constexpr Max = 'z'; // 0x7E; + return static_cast(Min + rand() % (Max - Min + 1)); } -} -void moveCursor(Buffer& _sink, unsigned x, unsigned y) -{ - writeChar(_sink, '\033'); - writeChar(_sink, '['); - writeNumber(_sink, y); - writeChar(_sink, ';'); - writeNumber(_sink, x); - writeChar(_sink, 'H'); -} - -void setTextColor(Buffer& _sink, uint8_t r, uint8_t g, uint8_t b) -{ - _sink.write("\033[38;2;"); - writeNumber(_sink, r & 0xFF); - writeChar(_sink, ';'); - writeNumber(_sink, g & 0xFF); - writeChar(_sink, ';'); - writeNumber(_sink, b & 0xFF); - writeChar(_sink, 'm'); -} - -void setBackgroundColor(Buffer& _sink, uint8_t r, uint8_t g, uint8_t b) -{ - _sink.write("\033[48;2;"); - writeNumber(_sink, r & 0xFF); - writeChar(_sink, ';'); - writeNumber(_sink, g & 0xFF); - writeChar(_sink, ';'); - writeNumber(_sink, b & 0xFF); - writeChar(_sink, 'm'); -} - -class ManyLines: public Test -{ -public: - ManyLines() noexcept: Test("many_lines", "") {} + void writeChar(Buffer& _sink, char ch) + { + _sink.write(std::string_view { &ch, 1 }); + } - void setup(unsigned short, unsigned short) override + void writeNumber(Buffer& _sink, unsigned _value) { - text.resize(4 * 1024 * 1024); - for (auto i = text.data(), e = i + text.size(); i != e; ++i) + unsigned remains = _value; + for (unsigned divisor = 1000000000; divisor != 0; divisor /= 10) { - char const value = randomAsciiChar(); - if (value % 26 != 0) - *i = value; - else - *i = '\n'; + auto const digit = remains / divisor; + remains -= digit * divisor; + + if (digit || (_value != remains) || (divisor == 1)) + writeChar(_sink, static_cast('0' + digit)); } } - void run(Buffer& _sink) noexcept override + void moveCursor(Buffer& _sink, unsigned x, unsigned y) { - while (_sink.good()) - _sink.write(text); + writeChar(_sink, '\033'); + writeChar(_sink, '['); + writeNumber(_sink, y); + writeChar(_sink, ';'); + writeNumber(_sink, x); + writeChar(_sink, 'H'); } -private: - std::string text; -}; + void setTextColor(Buffer& _sink, uint8_t r, uint8_t g, uint8_t b) + { + _sink.write("\033[38;2;"); + writeNumber(_sink, r & 0xFF); + writeChar(_sink, ';'); + writeNumber(_sink, g & 0xFF); + writeChar(_sink, ';'); + writeNumber(_sink, b & 0xFF); + writeChar(_sink, 'm'); + } -class LongLines: public Test -{ -public: - LongLines() noexcept: Test("long_lines", "") {} + void setBackgroundColor(Buffer& _sink, uint8_t r, uint8_t g, uint8_t b) + { + _sink.write("\033[48;2;"); + writeNumber(_sink, r & 0xFF); + writeChar(_sink, ';'); + writeNumber(_sink, g & 0xFF); + writeChar(_sink, ';'); + writeNumber(_sink, b & 0xFF); + writeChar(_sink, 'm'); + } - void run(Buffer& _sink) noexcept override + class ManyLines: public Test { - while (_sink.good()) + public: + ManyLines() noexcept: Test("many_lines", "") {} + + void setup(unsigned short, unsigned short) override { - writeChar(_sink, randomAsciiChar()); + text.resize(4 * 1024 * 1024); + for (auto i = text.data(), e = i + text.size(); i != e; ++i) + { + char const value = randomAsciiChar(); + if (value % 26 != 0) + *i = value; + else + *i = '\n'; + } } - } -}; -class SgrFgColoredText: public Test -{ -public: - SgrFgColoredText() noexcept: Test("sgr_fg_lines", "") {} + void run(Buffer& _sink) noexcept override + { + while (_sink.good()) + _sink.write(text); + } - unsigned short width = 80; - unsigned short height = 24; + private: + std::string text; + }; - void setup(unsigned short _width, unsigned short _height) noexcept override + class LongLines: public Test { - width = _width; - height = _height; - } + public: + LongLines() noexcept: Test("long_lines", "") {} + + void run(Buffer& _sink) noexcept override + { + while (_sink.good()) + { + writeChar(_sink, randomAsciiChar()); + } + } + }; - void run(Buffer& _sink) noexcept override + class SgrFgColoredText: public Test { - for (unsigned frameID = 0; _sink.good(); ++frameID) + public: + SgrFgColoredText() noexcept: Test("sgr_fg_lines", "") {} + + unsigned short width = 80; + unsigned short height = 24; + + void setup(unsigned short _width, unsigned short _height) noexcept override + { + width = _width; + height = _height; + } + + void run(Buffer& _sink) noexcept override { - for (u16 y = 0; y < height; ++y) + for (unsigned frameID = 0; _sink.good(); ++frameID) { - moveCursor(_sink, 1, y + 1u); - for (u16 x = 0; x < width; ++x) + for (u16 y = 0; y < height; ++y) { - auto const r = frameID; - auto const g = frameID + y; - auto const b = frameID + y + x; - - setTextColor(_sink, r & 0xff, g & 0xff, b & 0xff); - writeChar(_sink, static_cast('a' + (frameID + x + y) % ('z' - 'a'))); + moveCursor(_sink, 1, y + 1u); + for (u16 x = 0; x < width; ++x) + { + auto const r = frameID; + auto const g = frameID + y; + auto const b = frameID + y + x; + + setTextColor(_sink, r & 0xff, g & 0xff, b & 0xff); + writeChar(_sink, static_cast('a' + (frameID + x + y) % ('z' - 'a'))); + } } } } - } -}; + }; -class SgrFgBgColoredText: public Test -{ -public: - SgrFgBgColoredText() noexcept: Test("sgr_fg_bg_lines", "") {} + class SgrFgBgColoredText: public Test + { + public: + SgrFgBgColoredText() noexcept: Test("sgr_fg_bg_lines", "") {} - unsigned short width = 80; - unsigned short height = 24; + unsigned short width = 80; + unsigned short height = 24; - void setup(unsigned short _width, unsigned short _height) noexcept override - { - width = _width; - height = _height; - } + void setup(unsigned short _width, unsigned short _height) noexcept override + { + width = _width; + height = _height; + } - void run(Buffer& _sink) noexcept override - { - for (unsigned frameID = 0; _sink.good(); ++frameID) + void run(Buffer& _sink) noexcept override { - for (u16 y = 0; y < height; ++y) + for (unsigned frameID = 0; _sink.good(); ++frameID) { - moveCursor(_sink, 1, y + 1u); - for (u16 x = 0; x < width; ++x) + for (u16 y = 0; y < height; ++y) { - auto r = static_cast(frameID); - auto g = static_cast(frameID + y); - auto b = static_cast(frameID + y + x); - setTextColor(_sink, r, g, b); - - r = static_cast(frameID + y + x); - g = static_cast(frameID + y); - b = static_cast(frameID); - setBackgroundColor(_sink, r, g, b); - - writeChar(_sink, static_cast('a' + (frameID + x + y) % ('z' - 'a'))); + moveCursor(_sink, 1, y + 1u); + for (u16 x = 0; x < width; ++x) + { + auto r = static_cast(frameID); + auto g = static_cast(frameID + y); + auto b = static_cast(frameID + y + x); + setTextColor(_sink, r, g, b); + + r = static_cast(frameID + y + x); + g = static_cast(frameID + y); + b = static_cast(frameID); + setBackgroundColor(_sink, r, g, b); + + writeChar(_sink, static_cast('a' + (frameID + x + y) % ('z' - 'a'))); + } } } } - } -}; - -class Binary: public Test -{ -public: - Binary() noexcept: Test("binary", "") {} + }; - void setup(unsigned short, unsigned short) override + class Binary: public Test { - text.resize(4 * 1024 * 1024); - for (auto i = text.data(), e = i + text.size(); i != e; ++i) + public: + Binary() noexcept: Test("binary", "") {} + + void setup(unsigned short, unsigned short) override { - char const value = randomAsciiChar(); - if (value % 26 != 0) - *i = value; - else - *i = '\n'; + text.resize(4 * 1024 * 1024); + for (auto i = text.data(), e = i + text.size(); i != e; ++i) + { + char const value = randomAsciiChar(); + if (value % 26 != 0) + *i = value; + else + *i = '\n'; + } } - } - void run(Buffer& _sink) noexcept override - { - while (_sink.good()) + void run(Buffer& _sink) noexcept override { - _sink.write(text); + while (_sink.good()) + { + _sink.write(text); + } } - } - void teardown(Buffer& _sink) noexcept override + void teardown(Buffer& _sink) noexcept override { _sink.write("\033c"); } + + private: + std::string text; + }; + + class Line: public Test { - _sink.write("\033c"); - } + public: + Line(std::string name, std::string text): Test(name, ""), text { text } {} + void setup(unsigned short, unsigned short) override {} -private: - std::string text; -}; + void run(Buffer& _sink) noexcept override + { + for (int i = 0; i < 10000; ++i) + { + while (_sink.good()) + _sink.write(text); + } + } -} + private: + std::string text; + }; +} // namespace unique_ptr many_lines() { @@ -386,4 +395,33 @@ unique_ptr binary() return make_unique(); } +unique_ptr ascii_line(size_t N) +{ + auto name = std::to_string(N) + " chars per line"; + auto text = std::string(N, 'a') + std::string { "\n" }; + return make_unique(name, text); } + +unique_ptr sgr_line(size_t N) +{ + auto name = std::to_string(N) + " chars with sgr per line"; + std::string text {}; + text += std::string { "\033[38;2;20;200;200m" }; + text += std::string(N, 'a'); + text += std::string { "\n" }; + text += std::string { "\033[38;2;255;255;255m" }; + return make_unique(name, text); +} + +unique_ptr sgrbg_line(size_t N) +{ + auto name = std::to_string(N) + " chars with sgr and bg per line"; + 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" }; + text += std::string { "\n" }; + return make_unique(name, text); +} + +} // namespace contour::termbench::tests diff --git a/libtermbench/termbench.h b/libtermbench/termbench.h index ec0f64c..fc2cae6 100644 --- a/libtermbench/termbench.h +++ b/libtermbench/termbench.h @@ -27,21 +27,14 @@ namespace contour::termbench struct Buffer { -public: - explicit Buffer(size_t _maxWriteSizeMB) noexcept: - maxWriteSize{_maxWriteSizeMB * 1024 * 1024} - {} + public: + explicit Buffer(size_t _maxWriteSizeMB) noexcept: maxWriteSize { _maxWriteSizeMB * 1024 * 1024 } {} - bool good() const noexcept - { - return nwritten < maxWriteSize; - } + bool good() const noexcept { return nwritten < maxWriteSize; } void write(std::string_view _data) noexcept { - auto const n = nwritten + _data.size() < maxWriteSize - ? _data.size() - : maxWriteSize - nwritten; + auto const n = nwritten + _data.size() < maxWriteSize ? _data.size() : maxWriteSize - nwritten; auto i = _data.data(); auto p = data.data() + nwritten; auto e = data.data() + nwritten + n; @@ -51,30 +44,30 @@ struct Buffer nwritten += n; } - std::string_view output() const noexcept { return std::string_view{data.data(), nwritten}; } + std::string_view output() const noexcept { return std::string_view { data.data(), nwritten }; } void clear() noexcept { nwritten = 0; } bool empty() const noexcept { return nwritten == 0; } -private: + private: size_t maxWriteSize = 4 * 1024 * 1024; - std::array data{}; + std::array data {}; size_t nwritten = 0; }; /// Describes a single test. struct Test { - std::string_view name; - std::string_view description; + std::string name; + std::string description; virtual ~Test() = default; - Test(std::string_view _name, std::string_view _description) noexcept: - name{_name}, - description{_description} - {} + Test(std::string _name, std::string _description) noexcept: + name { _name }, description { _description } + { + } virtual void setup(unsigned short, unsigned short) {} virtual void run(Buffer&) noexcept = 0; @@ -90,7 +83,7 @@ struct Result class Benchmark { -public: + public: Benchmark(std::function _writer, size_t _testSizeMB, unsigned short _width, @@ -105,7 +98,7 @@ class Benchmark std::vector const& results() const noexcept { return results_; } -private: + private: std::function writer_; std::function beforeTest_; size_t testSizeMB_; @@ -116,14 +109,17 @@ class Benchmark std::vector results_; }; -} +} // namespace contour::termbench // Holds a set of pre-defined terminal benchmark tests. namespace contour::termbench::tests { - std::unique_ptr many_lines(); - std::unique_ptr long_lines(); - std::unique_ptr sgr_fg_lines(); - std::unique_ptr sgr_fgbg_lines(); - std::unique_ptr binary(); -} +std::unique_ptr many_lines(); +std::unique_ptr long_lines(); +std::unique_ptr sgr_fg_lines(); +std::unique_ptr sgr_fgbg_lines(); +std::unique_ptr binary(); +std::unique_ptr ascii_line(size_t); +std::unique_ptr sgr_line(size_t); +std::unique_ptr sgrbg_line(size_t); +} // namespace contour::termbench::tests diff --git a/scripts/Xvfb-bench-run.sh b/scripts/Xvfb-bench-run.sh new file mode 100644 index 0000000..f419fc9 --- /dev/null +++ b/scripts/Xvfb-bench-run.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env sh + +# +# Usage: Xvfb-contour-run.sh + + +Xvfb $DISPLAY -screen 0 1280x1024x24 & +XVFB_PID=$! +trap "kill $XVFB_PID" EXIT + +sleep 3 + +TB_BIN=$PWD/build/tb/tb + +contour $TB_BIN --output contour_results +alacritty -e $TB_BIN --output alacritty_results +kitty -e $TB_BIN --output kitty_results +xterm -e $TB_BIN --output xterm_results + +if [[ "$GITHUB_OUTPUT" != "" ]]; then + echo "exitCode=$?" >> "$GITHUB_OUTPUT" +fi diff --git a/scripts/check-includes.sh b/scripts/check-includes.sh new file mode 100755 index 0000000..97d5ab1 --- /dev/null +++ b/scripts/check-includes.sh @@ -0,0 +1,14 @@ +#! /bin/bash + +grep -R --include '*.cpp' -E '^#.*include ".*"$' src/ +rv1=$? + +grep -R --include '*.h' -E '^#.*include ".*"$' src/ +rv2=$? + +if [[ $rv1 -eq 0 || $rv2 -eq 0 ]]; then + echo 1>&2 "Error: found #include \"...\" in C++ files." + exit 1 +else + echo "All good. ;-)" +fi diff --git a/scripts/install-deps.sh b/scripts/install-deps.sh index 3fcb4c6..16dc616 100755 --- a/scripts/install-deps.sh +++ b/scripts/install-deps.sh @@ -11,7 +11,6 @@ install_deps_ubuntu() cmake g++ make - libfmt-dev ) if [[ "${RELEASE}" < "19.04" ]]; then @@ -34,13 +33,6 @@ main_linux() ;; esac } - -main_darwin() -{ - # brew install cmake clang? - brew install fmt -} - main() { case "$OSTYPE" in @@ -48,7 +40,6 @@ main() main_linux ;; darwin*) - main_darwin ;; *) echo "OS not supported." diff --git a/scripts/plot_results.jl b/scripts/plot_results.jl new file mode 100644 index 0000000..d40868d --- /dev/null +++ b/scripts/plot_results.jl @@ -0,0 +1,92 @@ +using CairoMakie + + +function parse_line(line) + if count("MB",line) > 0 + return parse(Float64,strip(split(split(line,',')[2],"MB/s")[1])) + else # KB + return parse(Float64,split(split(split(line,",")[2], "(")[1]," ")[2]) / 1024 + end +end + +function insert_from_data(ax, file_name, r,g,b) + data = split(open(io->read(io, String), file_name), '\n') + terminal_name = split(file_name,"_")[1] + + ascii_lines = [] + sgr_lines = [] + sgr_bg_lines = [] + for el in data + if occursin("chars per line", el) + push!(ascii_lines, el) + end + if occursin("chars with sgr per line", el) + push!(sgr_lines, el) + end + if occursin("chars with sgr and bg per line", el) + push!(sgr_bg_lines, el) + end + end + + ascii_speed = [ parse_line(val) for val in ascii_lines] + sgr_speed = [ parse_line(val) for val in sgr_lines] + sgr_bg_speed = [ parse_line(val) for val in sgr_bg_lines] + + lines!(ax,ascii_speed, label= terminal_name * "_ascii", color = RGBf(r, g, b)) + lines!(ax,sgr_speed, label=terminal_name*"_sgr", color = RGBf(r * 0.7 , g* 0.7 , b* 0.7 )) + lines!(ax,sgr_bg_speed, label=terminal_name*"_sgr_and_bg", color = RGBf(r * 0.4 , g* 0.4 , b* 0.4 )) + +end + +function insert_from_data_ascii(ax, file_name) + data = split(open(io->read(io, String), file_name), '\n') + terminal_name = split(file_name,"_")[1] + + ascii_lines = [] + sgr_lines = [] + sgr_bg_lines = [] + for el in data + if occursin("chars per line", el) + push!(ascii_lines, el) + end + if occursin("chars with sgr per line", el) + push!(sgr_lines, el) + end + if occursin("chars with sgr and bg per line", el) + push!(sgr_bg_lines, el) + end + end + + ascii_speed = [ parse_line(val) for val in ascii_lines] + + lines!(ax,ascii_speed, label= terminal_name * "_ascii") +end + + + +fig = Figure() +ax = Axis(fig[1,1], xlabel = "Length of line", ylabel = "throughput, MB/s") +ls = [] + +insert_from_data(ax,"contour_results", 1.0, 0.5 ,0.5) +insert_from_data(ax,"alacritty_results", 0.5, 1.0, 0.5) +insert_from_data(ax,"xterm_results", 0.5, 0.5, 1.0) +insert_from_data(ax,"kitty_results", 0.0, 0.8, 1.0) + +fig[1, 2] = Legend(fig, ax,framevisible = false) + +save("results_full.png", fig) + + + +fig = Figure() +ax = Axis(fig[1,1], xlabel = "Length of line", ylabel = "throughput, MB/s") +ls = [] + +insert_from_data_ascii(ax,"contour_results") +insert_from_data_ascii(ax,"alacritty_results") +insert_from_data_ascii(ax,"xterm_results") +insert_from_data_ascii(ax,"kitty_results") +fig[1, 2] = Legend(fig, ax,framevisible = false) + +save("results_ascii.png", fig) diff --git a/tb/CMakeLists.txt b/tb/CMakeLists.txt index 08f91d4..62a5ffa 100644 --- a/tb/CMakeLists.txt +++ b/tb/CMakeLists.txt @@ -1,7 +1,7 @@ include(GNUInstallDirs) add_executable(tb main.cpp) -target_link_libraries(tb PRIVATE termbench fmt::fmt-header-only) +target_link_libraries(tb PRIVATE termbench) # Set the RPATH so that the executable can find the shared libraries # when installed in a non-standard location diff --git a/tb/main.cpp b/tb/main.cpp index d576993..1ffcf38 100644 --- a/tb/main.cpp +++ b/tb/main.cpp @@ -13,11 +13,13 @@ */ #include -#include + #include #include +#include +#include +#include #include -#include using std::cerr; using std::cout; @@ -28,85 +30,87 @@ using namespace std::string_view_literals; using namespace std::placeholders; #if !defined(_WIN32) -#include -#include + #include + + #include #else -#include + #include #endif namespace { - std::pair getTerminalSize() noexcept - { - auto const DefaultSize = std::pair{80, 24}; +std::pair getTerminalSize() noexcept +{ + auto const DefaultSize = std::pair { 80, 24 }; #if !defined(_WIN32) - winsize ws; - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) - return DefaultSize; - return {ws.ws_col, ws.ws_row}; -#else - // TODO: Windows + winsize ws; + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) return DefaultSize; + return { ws.ws_col, ws.ws_row }; +#else + // TODO: Windows + return DefaultSize; #endif - } - - void nullWrite(char const*, size_t) - { - } +} - void chunkedWriteToStdout(char const* _data, size_t _size) - { - auto constexpr PageSize = 4096; // 8192; +void nullWrite(char const*, size_t) +{ +} - #if defined(_WIN32) - HANDLE stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD nwritten{}; - #endif +void chunkedWriteToStdout(char const* _data, size_t _size) +{ + auto constexpr PageSize = 4096; // 8192; - while (_size >= PageSize) - { - #if !defined(_WIN32) - auto const n = write(STDOUT_FILENO, _data, PageSize); - if (n < 0) - perror("write"); - _data += n; - _size -= static_cast(n); - #else - WriteConsoleA(stdoutHandle, _data, static_cast(_size), &nwritten, nullptr); - #endif - } +#if defined(_WIN32) + HANDLE stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD nwritten {}; +#endif - #if !defined(_WIN32) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wunused-result" - write(STDOUT_FILENO, _data, _size); - #pragma GCC diagnostic pop - #else + while (_size >= PageSize) + { +#if !defined(_WIN32) + auto const n = write(STDOUT_FILENO, _data, PageSize); + if (n < 0) + perror("write"); + _data += n; + _size -= static_cast(n); +#else WriteConsoleA(stdoutHandle, _data, static_cast(_size), &nwritten, nullptr); - #endif +#endif } + +#if !defined(_WIN32) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-result" + write(STDOUT_FILENO, _data, _size); + #pragma GCC diagnostic pop +#else + WriteConsoleA(stdoutHandle, _data, static_cast(_size), &nwritten, nullptr); +#endif } +} // namespace int main(int argc, char const* argv[]) { - #if defined(_WIN32) +#if defined(_WIN32) { HANDLE stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleMode(stdoutHandle, ENABLE_VIRTUAL_TERMINAL_PROCESSING); } - #endif +#endif // TODO: Also run against NullSink to get a base value. auto [width, height] = getTerminalSize(); size_t testSizeMB = 32; bool nullSink = false; + std::string fileout {}; for (int i = 1; i < argc; ++i) { if (argv[i] == "--null-sink"sv) { - cout << fmt::format("Using null-sink.\n"); + cout << std::format("Using null-sink.\n"); nullSink = true; } else if (argv[i] == "--size"sv && i + 1 < argc) @@ -116,35 +120,57 @@ int main(int argc, char const* argv[]) } else if (argv[i] == "--help"sv || argv[i] == "-h"sv) { - cout << fmt::format("{} [--null-sink] [--size MB]\n", argv[0]); + cout << std::format("{} [--null-sink] [--size MB]\n", argv[0]); return EXIT_SUCCESS; } + else if (argv[i] == "--output"sv && i + 1 < argc) + { + ++i; + fileout = argv[i]; + } else { - cerr << fmt::format("Invalid argument usage.\n"); + cerr << std::format("Invalid argument usage.\n"); return EXIT_FAILURE; } } - contour::termbench::Benchmark tb{ - nullSink ? nullWrite : chunkedWriteToStdout, - testSizeMB, // MB per test - width, - height - }; + contour::termbench::Benchmark tb { nullSink ? nullWrite : chunkedWriteToStdout, + testSizeMB, // MB per test + width, + height }; // mlfgb tb.add(contour::termbench::tests::many_lines()); tb.add(contour::termbench::tests::long_lines()); tb.add(contour::termbench::tests::sgr_fg_lines()); tb.add(contour::termbench::tests::sgr_fgbg_lines()); - //tb.add(contour::termbench::tests::binary()); + tb.add(contour::termbench::tests::binary()); + // tb.add(contour::termbench::tests::binary()); + constexpr size_t Max_lines { 20 }; + for (size_t i = 0; i < Max_lines; ++i) + tb.add(contour::termbench::tests::ascii_line(i)); + for (size_t i = 0; i < Max_lines; ++i) + tb.add(contour::termbench::tests::sgr_line(i)); + for (size_t i = 0; i < Max_lines; ++i) + tb.add(contour::termbench::tests::sgrbg_line(i)); + + cout << "\033[8;30;100t"; + cout.flush(); tb.runAll(); cout << "\033[m\033[H\033[J"; cout.flush(); - tb.summarize(cout); + if (fileout.empty()) + tb.summarize(cout); + else + { + cout << "Writing summary into " << fileout << std::endl; + std::ofstream writerToFile; + writerToFile.open(fileout); + tb.summarize(writerToFile); + } return EXIT_SUCCESS; } diff --git a/xterm_results b/xterm_results new file mode 100644 index 0000000..988909c --- /dev/null +++ b/xterm_results @@ -0,0 +1,72 @@ +All 65 tests finished. +--------------------- + + many_lines: 0.0669 seconds, 47.833 MB/s (normalized: 25.511 KB/s) + long_lines: 0.0409 seconds, 78.240 MB/s (normalized: 41.728 KB/s) + sgr_fg_lines: 1.0000 seconds, 32.000 MB/s (normalized: 17.067 KB/s) + sgr_fg_bg_lines: 0.0544 seconds, 58.824 MB/s (normalized: 31.373 KB/s) + binary: 0.0704 seconds, 45.455 MB/s (normalized: 24.242 KB/s) + 0 chars per line: 7.0154 seconds, 4.473 MB/s (normalized: 2.386 KB/s) + 1 chars per line: 3.0870 seconds, 8.269 MB/s (normalized: 4.410 KB/s) + 2 chars per line: 2.0985 seconds, 10.720 MB/s (normalized: 5.717 KB/s) + 3 chars per line: 2.0192 seconds, 14.599 MB/s (normalized: 7.786 KB/s) + 4 chars per line: 1.0792 seconds, 17.857 MB/s (normalized: 9.524 KB/s) + 5 chars per line: 1.0670 seconds, 19.162 MB/s (normalized: 10.220 KB/s) + 6 chars per line: 1.0438 seconds, 22.253 MB/s (normalized: 11.868 KB/s) + 7 chars per line: 1.0265 seconds, 25.296 MB/s (normalized: 13.491 KB/s) + 8 chars per line: 1.0188 seconds, 26.936 MB/s (normalized: 14.366 KB/s) + 9 chars per line: 1.0138 seconds, 28.120 MB/s (normalized: 14.997 KB/s) + 10 chars per line: 1.0062 seconds, 30.132 MB/s (normalized: 16.070 KB/s) + 11 chars per line: 1.0072 seconds, 29.851 MB/s (normalized: 15.920 KB/s) + 12 chars per line: 0.0974 seconds, 32.854 MB/s (normalized: 17.522 KB/s) + 13 chars per line: 0.0937 seconds, 34.152 MB/s (normalized: 18.214 KB/s) + 14 chars per line: 0.0859 seconds, 37.253 MB/s (normalized: 19.868 KB/s) + 15 chars per line: 0.0801 seconds, 39.950 MB/s (normalized: 21.307 KB/s) + 16 chars per line: 0.0840 seconds, 38.095 MB/s (normalized: 20.317 KB/s) + 17 chars per line: 0.0785 seconds, 40.764 MB/s (normalized: 21.741 KB/s) + 18 chars per line: 0.0733 seconds, 43.656 MB/s (normalized: 23.283 KB/s) + 19 chars per line: 0.0749 seconds, 42.724 MB/s (normalized: 22.786 KB/s) + 0 chars with sgr per line: 0.0585 seconds, 54.701 MB/s (normalized: 29.174 KB/s) + 1 chars with sgr per line: 0.0592 seconds, 54.054 MB/s (normalized: 28.829 KB/s) + 2 chars with sgr per line: 0.0641 seconds, 49.922 MB/s (normalized: 26.625 KB/s) + 3 chars with sgr per line: 0.0583 seconds, 54.889 MB/s (normalized: 29.274 KB/s) + 4 chars with sgr per line: 0.0564 seconds, 56.738 MB/s (normalized: 30.260 KB/s) + 5 chars with sgr per line: 0.0562 seconds, 56.940 MB/s (normalized: 30.368 KB/s) + 6 chars with sgr per line: 0.0588 seconds, 54.422 MB/s (normalized: 29.025 KB/s) + 7 chars with sgr per line: 0.0583 seconds, 54.889 MB/s (normalized: 29.274 KB/s) + 8 chars with sgr per line: 0.0626 seconds, 51.118 MB/s (normalized: 27.263 KB/s) + 9 chars with sgr per line: 0.0539 seconds, 59.369 MB/s (normalized: 31.664 KB/s) + 10 chars with sgr per line: 0.0552 seconds, 57.971 MB/s (normalized: 30.918 KB/s) + 11 chars with sgr per line: 0.0553 seconds, 57.866 MB/s (normalized: 30.862 KB/s) + 12 chars with sgr per line: 0.0553 seconds, 57.866 MB/s (normalized: 30.862 KB/s) + 13 chars with sgr per line: 0.0555 seconds, 57.658 MB/s (normalized: 30.751 KB/s) + 14 chars with sgr per line: 0.0530 seconds, 60.377 MB/s (normalized: 32.201 KB/s) + 15 chars with sgr per line: 0.0549 seconds, 58.288 MB/s (normalized: 31.087 KB/s) + 16 chars with sgr per line: 0.0535 seconds, 59.813 MB/s (normalized: 31.900 KB/s) + 17 chars with sgr per line: 0.0536 seconds, 59.701 MB/s (normalized: 31.841 KB/s) + 18 chars with sgr per line: 0.0560 seconds, 57.143 MB/s (normalized: 30.476 KB/s) + 19 chars with sgr per line: 0.0494 seconds, 64.777 MB/s (normalized: 34.548 KB/s) + 0 chars with sgr and bg per line: 5.0501 seconds, 5.817 MB/s (normalized: 3.102 KB/s) + 1 chars with sgr and bg per line: 5.0544 seconds, 5.772 MB/s (normalized: 3.078 KB/s) + 2 chars with sgr and bg per line: 5.0539 seconds, 5.777 MB/s (normalized: 3.081 KB/s) + 3 chars with sgr and bg per line: 5.0281 seconds, 6.059 MB/s (normalized: 3.232 KB/s) + 4 chars with sgr and bg per line: 5.0227 seconds, 6.122 MB/s (normalized: 3.265 KB/s) + 5 chars with sgr and bg per line: 5.0209 seconds, 6.143 MB/s (normalized: 3.276 KB/s) + 6 chars with sgr and bg per line: 5.0081 seconds, 6.298 MB/s (normalized: 3.359 KB/s) + 7 chars with sgr and bg per line: 5.0036 seconds, 6.354 MB/s (normalized: 3.389 KB/s) + 8 chars with sgr and bg per line: 5.0058 seconds, 6.327 MB/s (normalized: 3.374 KB/s) + 9 chars with sgr and bg per line: 4.0964 seconds, 6.446 MB/s (normalized: 3.438 KB/s) + 10 chars with sgr and bg per line: 4.0950 seconds, 6.465 MB/s (normalized: 3.448 KB/s) + 11 chars with sgr and bg per line: 4.0834 seconds, 6.620 MB/s (normalized: 3.531 KB/s) + 12 chars with sgr and bg per line: 4.0772 seconds, 6.706 MB/s (normalized: 3.576 KB/s) + 13 chars with sgr and bg per line: 4.0710 seconds, 6.794 MB/s (normalized: 3.623 KB/s) + 14 chars with sgr and bg per line: 4.0659 seconds, 6.868 MB/s (normalized: 3.663 KB/s) + 15 chars with sgr and bg per line: 4.0617 seconds, 6.931 MB/s (normalized: 3.696 KB/s) + 16 chars with sgr and bg per line: 4.0684 seconds, 6.832 MB/s (normalized: 3.644 KB/s) + 17 chars with sgr and bg per line: 4.0515 seconds, 7.087 MB/s (normalized: 3.780 KB/s) + 18 chars with sgr and bg per line: 4.0478 seconds, 7.146 MB/s (normalized: 3.811 KB/s) + 19 chars with sgr and bg per line: 4.0410 seconds, 7.256 MB/s (normalized: 3.870 KB/s) + all tests: 147.0179 seconds, 14.132 MB/s (normalized: 7.537 KB/s) + + screen size: 80x24 + data size: 32.000 MB