From 0cc4fad6e6d00f13a7325d9c125f4900add09820 Mon Sep 17 00:00:00 2001 From: orefkov Date: Sat, 5 Apr 2025 17:21:11 +0300 Subject: [PATCH] First commit --- .clang-format | 1481 ++++ .clang-tidy | 175 + .clangd | 3 + .editorconfig | 9 + .gitattributes | 28 + .gitignore | 9 + .gitmodules | 3 + CMakeLists.txt | 90 + CMakePresets.json | 191 + LICENSE | 21 + ThirdParty/simdutf | 1 + bench/CMakeLists.txt | 16 + bench/bench.h | 12 + bench/bench.js | 1 + bench/bench_str.cpp | 1906 +++++ bench/comments.txt | 351 + bench/header.txt | 270 + bench/process_result.cpp | 356 + bench/results.css | 105 + bench/results.html | 3769 ++++++++++ ... E5-2682 v4, Ubuntu 22 (WSL), Clang-21.txt | 778 ++ ...on E5-2682 v4, Ubuntu 22 (WSL), GCC-13.txt | 778 ++ ...-Xeon E5-2682 v4, Windows 10, Clang-19.txt | 777 ++ ...3-Xeon E5-2682 v4, Windows 10, MSVC-19.txt | 777 ++ ...Xeon E5-2682 v4, WASM Chrome, Clang-21.txt | 783 ++ docs/Doxyfile | 2970 ++++++++ docs/overview.md | 739 ++ for_debug/readme.md | 67 + for_debug/simstr.natvis | 33 + for_debug/simstr_pretty_print.py | 202 + include/simstr/simple_unicode.h | 21 + include/simstr/sstring.h | 6340 +++++++++++++++++ include/simstr/strexpr.h | 986 +++ readme.md | 89 + src/simple_unicode.cpp | 3018 ++++++++ src/sstring.cpp | 548 ++ tests/CMakeLists.txt | 11 + tests/test_str.cpp | 1754 +++++ 38 files changed, 29468 insertions(+) create mode 100644 .clang-format create mode 100644 .clang-tidy create mode 100644 .clangd create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 CMakeLists.txt create mode 100644 CMakePresets.json create mode 100644 LICENSE create mode 160000 ThirdParty/simdutf create mode 100644 bench/CMakeLists.txt create mode 100644 bench/bench.h create mode 100644 bench/bench.js create mode 100644 bench/bench_str.cpp create mode 100644 bench/comments.txt create mode 100644 bench/header.txt create mode 100644 bench/process_result.cpp create mode 100644 bench/results.css create mode 100644 bench/results.html create mode 100644 bench/results/000-Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21.txt create mode 100644 bench/results/001-Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13.txt create mode 100644 bench/results/002-Xeon E5-2682 v4, Windows 10, Clang-19.txt create mode 100644 bench/results/003-Xeon E5-2682 v4, Windows 10, MSVC-19.txt create mode 100644 bench/results/004-Xeon E5-2682 v4, WASM Chrome, Clang-21.txt create mode 100644 docs/Doxyfile create mode 100644 docs/overview.md create mode 100644 for_debug/readme.md create mode 100644 for_debug/simstr.natvis create mode 100644 for_debug/simstr_pretty_print.py create mode 100644 include/simstr/simple_unicode.h create mode 100644 include/simstr/sstring.h create mode 100644 include/simstr/strexpr.h create mode 100644 readme.md create mode 100644 src/simple_unicode.cpp create mode 100644 src/sstring.cpp create mode 100644 tests/CMakeLists.txt create mode 100644 tests/test_str.cpp diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..0522d69 --- /dev/null +++ b/.clang-format @@ -0,0 +1,1481 @@ +# -*- mode: yaml -*- +# vim: ft=yaml +# +# This file provides Yandex.Maps source code formatting rules +# (https://wiki.yandex-team.ru/JandeksKarty/development/fordevelopers/codingstyle) +# understandable by the clang-format +# (http://clang.llvm.org/docs/ClangFormat.html) +# +# This configuration is valid for clang-format version 7.0.0 +# +# Full option list can be found here +# https://releases.llvm.org/7.0.0/tools/clang/docs/ClangFormatStyleOptions.html + +# Language, this format style is targeted at. +# +# Possible values: +# +# None - Do not use. +# Cpp - Should be used for C, C++, ObjectiveC, ObjectiveC++. +# JavaScript - Should be used for JavaScript. +# Proto - Should be used for Protocol Buffers +# (https://developers.google.com/protocol-buffers/). +Language: Cpp + +# The style used for all options not specifically set in the configuration. +# +# This option is supported only in the clang-format configuration +# (both within -style='{...}' and the .clang-format file). +# +# Possible values: +# +# LLVM - A style complying with the LLVM coding standards +# Google - A style complying with Google’s C++ style guide +# Chromium - A style complying with Chromium’s style guide +# Mozilla - A style complying with Mozilla’s style guide +# WebKit - A style complying with WebKit’s style guide +BasedOnStyle: LLVM + +# **AccessModifierOffset** (``int``) +# The extra indent or outdent of access modifiers, e.g. ``public:``. +AccessModifierOffset: -4 + +# **AlignAfterOpenBracket** (``BracketAlignmentStyle``) +# If ``true``, horizontally aligns arguments after an open bracket. +# +# This applies to round brackets (parentheses), angle brackets and square brackets. +# +# Possible values: +# +# * ``BAS_Align`` (in configuration: ``Align``) Align parameters on the open bracket, e.g.: +# +# .. parsed-literal:: +# +# someLongFunction(argument1, +# argument2); +# +# * ``BAS_DontAlign`` (in configuration: ``DontAlign``) Don't align, instead use ``ContinuationIndentWidth``, e.g.: +# +# .. parsed-literal:: +# +# someLongFunction(argument1, +# argument2); +# +# * ``BAS_AlwaysBreak`` (in configuration: ``AlwaysBreak``) Always break after an open bracket, if the parameters don't fit on a single line, e.g.: +# +# .. parsed-literal:: +# +# someLongFunction( +# argument1, argument2); +AlignAfterOpenBracket: AlwaysBreak + +# **AlignConsecutiveAssignments** (``bool``) +# If ``true``, aligns consecutive assignments. +# +# This will align the assignment operators of consecutive lines. This will result in formattings like +# +# int aaaa = 12; +# int b = 23; +# int ccc = 23; +AlignConsecutiveAssignments: false + +# **AlignConsecutiveDeclarations** (``bool``) +# If ``true``, aligns consecutive declarations. +# +# This will align the declaration names of consecutive lines. This will result in formattings like +# +# int aaaa = 12; +# float b = 23; +# std::string ccc = 23; +AlignConsecutiveDeclarations: false + +# **AlignEscapedNewlines** (``EscapedNewlineAlignmentStyle``) +# Options for aligning backslashes in escaped newlines. +# +# Possible values: +# +# * ``ENAS_DontAlign`` (in configuration: ``DontAlign``) Don't align escaped newlines. +# +# .. parsed-literal:: +# +# #define A \\ +# int aaaa; \\ +# int b; \\ +# int dddddddddd; +# +# * ``ENAS_Left`` (in configuration: ``Left``) Align escaped newlines as far left as possible. +# +# .. parsed-literal:: +# +# true: +# #define A \\ +# int aaaa; \\ +# int b; \\ +# int dddddddddd; +# +# false: +# +# * ``ENAS_Right`` (in configuration: ``Right``) Align escaped newlines in the right-most column. +# +# .. parsed-literal:: +# +# #define A \\ +# int aaaa; \\ +# int b; \\ +# int dddddddddd; +AlignEscapedNewlines: Left + +# **AlignOperands** (``bool``) +# If ``true``, horizontally align operands of binary and ternary expressions. +# +# Specifically, this aligns operands of a single expression that needs to be split over multiple lines, e.g.: +# +# int aaa = bbbbbbbbbbbbbbb + +# ccccccccccccccc; +AlignOperands: true + +# **AlignTrailingComments** (``bool``) +# If ``true``, aligns trailing comments. +# +# true: false: +# int a; // My comment a vs. int a; // My comment a +# int b = 2; // comment b int b = 2; // comment about b +AlignTrailingComments: true + +# **AllowAllParametersOfDeclarationOnNextLine** (``bool``) +# If the function declaration doesn't fit on a line, allow putting all parameters of a function declaration onto the next line even if ``BinPackParameters`` is ``false``. +# +# true: +# void myFunction( +# int a, int b, int c, int d, int e); +# +# false: +# void myFunction(int a, +# int b, +# int c, +# int d, +# int e); +AllowAllParametersOfDeclarationOnNextLine: true + +# **AllowShortBlocksOnASingleLine** (``bool``) +# Allows contracting simple braced statements to a single line. +# +# E.g., this allows ``if (a) { return; }`` to be put on a single line. +AllowShortBlocksOnASingleLine: false + +# **AllowShortCaseLabelsOnASingleLine** (``bool``) +# If ``true``, short case labels will be contracted to a single line. +# +# true: false: +# switch (a) { vs. switch (a) { +# case 1: x = 1; break; case 1: +# case 2: return; x = 1; +# } break; +# case 2: +# return; +# } +AllowShortCaseLabelsOnASingleLine: false + +# **AllowShortFunctionsOnASingleLine** (``ShortFunctionStyle``) +# Dependent on the value, ``int f() { return 0; }`` can be put on a single line. +# +# Possible values: +# +# * ``SFS_None`` (in configuration: ``None``) Never merge functions into a single line. +# +# * ``SFS_InlineOnly`` (in configuration: ``InlineOnly``) Only merge functions defined inside a class. Same as "inline", except it does not implies "empty": i.e. top level empty functions are not merged either. +# +# .. parsed-literal:: +# +# class Foo { +# void f() { foo(); } +# }; +# void f() { +# foo(); +# } +# void f() { +# } +# +# * ``SFS_Empty`` (in configuration: ``Empty``) Only merge empty functions. +# +# .. parsed-literal:: +# +# void f() {} +# void f2() { +# bar2(); +# } +# +# * ``SFS_Inline`` (in configuration: ``Inline``) Only merge functions defined inside a class. Implies "empty". +# +# .. parsed-literal:: +# +# class Foo { +# void f() { foo(); } +# }; +# void f() { +# foo(); +# } +# void f() {} +# +# * ``SFS_All`` (in configuration: ``All``) Merge all functions fitting on a single line. +# +# .. parsed-literal:: +# +# class Foo { +# void f() { foo(); } +# }; +# void f() { bar(); } +AllowShortFunctionsOnASingleLine: Empty + +# **AllowShortIfStatementsOnASingleLine** (``bool``) +# If ``true``, ``if (a) return;`` can be put on a single line. +AllowShortIfStatementsOnASingleLine: false + +# **AllowShortLoopsOnASingleLine** (``bool``) +# If ``true``, ``while (true) continue;`` can be put on a single line. +AllowShortLoopsOnASingleLine: false + +# **AlwaysBreakAfterReturnType** (``ReturnTypeBreakingStyle``) +# The function declaration return type breaking style to use. +# +# Possible values: +# +# * ``RTBS_None`` (in configuration: ``None``) Break after return type automatically. ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. +# +# .. parsed-literal:: +# +# class A { +# int f() { return 0; }; +# }; +# int f(); +# int f() { return 1; } +# +# * ``RTBS_All`` (in configuration: ``All``) Always break after the return type. +# +# .. parsed-literal:: +# +# class A { +# int +# f() { +# return 0; +# }; +# }; +# int +# f(); +# int +# f() { +# return 1; +# } +# +# * ``RTBS_TopLevel`` (in configuration: ``TopLevel``) Always break after the return types of top-level functions. +# +# .. parsed-literal:: +# +# class A { +# int f() { return 0; }; +# }; +# int +# f(); +# int +# f() { +# return 1; +# } +# +# * ``RTBS_AllDefinitions`` (in configuration: ``AllDefinitions``) Always break after the return type of function definitions. +# +# .. parsed-literal:: +# +# class A { +# int +# f() { +# return 0; +# }; +# }; +# int f(); +# int +# f() { +# return 1; +# } +# +# * ``RTBS_TopLevelDefinitions`` (in configuration: ``TopLevelDefinitions``) Always break after the return type of top-level definitions. +# +# .. parsed-literal:: +# +# class A { +# int f() { return 0; }; +# }; +# int f(); +# int +# f() { +# return 1; +# } +AlwaysBreakAfterReturnType: None + +# **AlwaysBreakBeforeMultilineStrings** (``bool``) +# If ``true``, always break before multiline string literals. +# +# This flag is mean to make cases where there are multiple multiline strings in a file look more consistent. Thus, it will only take effect if wrapping the string at that point leads to it being indented ``ContinuationIndentWidth`` spaces from the start of the line. +# +# true: false: +# aaaa = vs. aaaa = "bbbb" +# "bbbb" "cccc"; +# "cccc"; +AlwaysBreakBeforeMultilineStrings: false + +# **AlwaysBreakTemplateDeclarations** (``BreakTemplateDeclarationsStyle``) +# The template declaration breaking style to use. +# +# Possible values: +# +# No: Do not force break before declaration. PenaltyBreakTemplateDeclaration is taken into account. +# +# template T foo() { +# } +# template T foo(int aaaaaaaaaaaaaaaaaaaaa, +# int bbbbbbbbbbbbbbbbbbbbb) { +# } +# +# MultiLine: Force break after template declaration only when the following declaration spans multiple lines. +# +# template T foo() { +# } +# template +# T foo(int aaaaaaaaaaaaaaaaaaaaa, +# int bbbbbbbbbbbbbbbbbbbbb) { +# } +# +# Yes: Always break after template declaration. +# +# template +# T foo() { +# } +# template +# T foo(int aaaaaaaaaaaaaaaaaaaaa, +# int bbbbbbbbbbbbbbbbbbbbb) { +# } +AlwaysBreakTemplateDeclarations: Yes + +# **BinPackArguments** (``bool``) +# If ``false``, a function call's arguments will either be all on the same line or will have one line each. +# +# true: +# void f() { +# f(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaa, +# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa); +# } +# +# false: +# void f() { +# f(aaaaaaaaaaaaaaaaaaaa, +# aaaaaaaaaaaaaaaaaaaa, +# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa); +# } +BinPackArguments: false + +# **BinPackParameters** (``bool``) +# If ``false``, a function declaration's or function definition's parameters will either all be on the same line or will have one line each. +# +# true: +# void f(int aaaaaaaaaaaaaaaaaaaa, int aaaaaaaaaaaaaaaaaaaa, +# int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {} +# +# false: +# void f(int aaaaaaaaaaaaaaaaaaaa, +# int aaaaaaaaaaaaaaaaaaaa, +# int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {} +BinPackParameters: false + +# **BraceWrapping** (``BraceWrappingFlags``) +# Control of individual brace wrapping cases. +# +# If ``BreakBeforeBraces`` is set to ``BS_Custom``, use this to specify how each individual brace case should be handled. Otherwise, this is ignored. +# +# # Example of usage: +# BreakBeforeBraces: Custom +# BraceWrapping: +# AfterEnum: true +# AfterStruct: false +# SplitEmptyFunction: false +# +# Nested configuration flags: +# +# * ``bool AfterClass`` Wrap class definitions. +# +# .. parsed-literal:: +# +# true: +# class foo {}; +# +# false: +# class foo +# {}; +# +# * ``bool AfterControlStatement`` Wrap control statements (``if``/``for``/``while``/``switch``/..). +# +# .. parsed-literal:: +# +# true: +# if (foo()) +# { +# } else +# {} +# for (int i = 0; i < 10; ++i) +# {} +# +# false: +# if (foo()) { +# } else { +# } +# for (int i = 0; i < 10; ++i) { +# } +# +# * ``bool AfterEnum`` Wrap enum definitions. +# +# .. parsed-literal:: +# +# true: +# enum X : int +# { +# B +# }; +# +# false: +# enum X : int { B }; +# +# * ``bool AfterFunction`` Wrap function definitions. +# +# .. parsed-literal:: +# +# true: +# void foo() +# { +# bar(); +# bar2(); +# } +# +# false: +# void foo() { +# bar(); +# bar2(); +# } +# +# * ``bool AfterNamespace`` Wrap namespace definitions. +# +# .. parsed-literal:: +# +# true: +# namespace +# { +# int foo(); +# int bar(); +# } +# +# false: +# namespace { +# int foo(); +# int bar(); +# } +# +# * ``bool AfterObjCDeclaration`` Wrap ObjC definitions (interfaces, implementations...). @autoreleasepool and @synchronized blocks are wrapped according to *AfterControlStatement* flag. +# +# * ``bool AfterStruct`` Wrap struct definitions. +# +# .. parsed-literal:: +# +# true: +# struct foo +# { +# int x; +# }; +# +# false: +# struct foo { +# int x; +# }; +# +# * ``bool AfterUnion`` Wrap union definitions. +# +# .. parsed-literal:: +# +# true: +# union foo +# { +# int x; +# } +# +# false: +# union foo { +# int x; +# } +# +# * ``bool AfterExternBlock`` Wrap extern blocks. +# +# .. parsed-literal:: +# +# true: +# extern "C" +# { +# int foo(); +# } +# +# false: +# extern "C" { +# int foo(); +# } +# +# * ``bool BeforeCatch`` Wrap before ``catch``. +# +# .. parsed-literal:: +# +# true: +# try { +# foo(); +# } +# catch () { +# } +# +# false: +# try { +# foo(); +# } catch () { +# } +# +# * ``bool BeforeElse`` Wrap before ``else``. +# +# .. parsed-literal:: +# +# true: +# if (foo()) { +# } +# else { +# } +# +# false: +# if (foo()) { +# } else { +# } +# +# * ``bool IndentBraces`` Indent the wrapped braces themselves. +# +# * ``bool SplitEmptyFunction`` If ``false``, empty function body can be put on a single line. This option is used only if the opening brace of the function has already been wrapped, i.e. the *AfterFunction* brace wrapping mode is set, and the function could/should not be put on a single line (as per *AllowShortFunctionsOnASingleLine* and constructor formatting options). +# +# .. parsed-literal:: +# +# int f() vs. inf f() +# {} { +# } +# +# * ``bool SplitEmptyRecord`` If ``false``, empty record (e.g. class, struct or union) body can be put on a single line. This option is used only if the opening brace of the record has already been wrapped, i.e. the *AfterClass* (for classes) brace wrapping mode is set. +# +# .. parsed-literal:: +# +# class Foo vs. class Foo +# {} { +# } +# +# * ``bool SplitEmptyNamespace`` If ``false``, empty namespace body can be put on a single line. This option is used only if the opening brace of the namespace has already been wrapped, i.e. the *AfterNamespace* brace wrapping mode is set. +# +# .. parsed-literal:: +# +# namespace Foo vs. namespace Foo +# {} { +# } +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterExternBlock: false + AfterFunction: false + AfterNamespace: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false + +# **BreakBeforeBinaryOperators** (``BinaryOperatorStyle``) +# The way to wrap binary operators. +# +# Possible values: +# +# * ``BOS_None`` (in configuration: ``None``) Break after operators. +# +# .. parsed-literal:: +# +# LooooooooooongType loooooooooooooooooooooongVariable = +# someLooooooooooooooooongFunction(); +# +# bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa == +# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa && +# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > +# ccccccccccccccccccccccccccccccccccccccccc; +# * ``BOS_NonAssignment`` (in configuration: ``NonAssignment``) Break before operators that aren't assignments. +# +# .. parsed-literal:: +# +# LooooooooooongType loooooooooooooooooooooongVariable = +# someLooooooooooooooooongFunction(); +# +# bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +# + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +# == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +# && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +# > ccccccccccccccccccccccccccccccccccccccccc; +# * ``BOS_All`` (in configuration: ``All``) Break before operators. +# +# .. parsed-literal:: +# +# LooooooooooongType loooooooooooooooooooooongVariable +# = someLooooooooooooooooongFunction(); +# +# bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +# + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +# == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +# && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +# > ccccccccccccccccccccccccccccccccccccccccc; +BreakBeforeBinaryOperators: NonAssignment + +# **BreakBeforeBraces** (``BraceBreakingStyle``) +# The brace breaking style to use. +# +# Possible values: +# +# * ``BS_Attach`` (in configuration: ``Attach``) Always attach braces to surrounding context. +# +# .. parsed-literal:: +# +# try { +# foo(); +# } catch () { +# } +# void foo() { bar(); } +# class foo {}; +# if (foo()) { +# } else { +# } +# enum X : int { A, B }; +# +# * ``BS_Linux`` (in configuration: ``Linux``) Like ``Attach``, but break before braces on function, namespace and class definitions. +# +# .. parsed-literal:: +# +# try { +# foo(); +# } catch () { +# } +# void foo() { bar(); } +# class foo +# { +# }; +# if (foo()) { +# } else { +# } +# enum X : int { A, B }; +# +# * ``BS_Mozilla`` (in configuration: ``Mozilla``) Like ``Attach``, but break before braces on enum, function, and record definitions. +# +# .. parsed-literal:: +# +# try { +# foo(); +# } catch () { +# } +# void foo() { bar(); } +# class foo +# { +# }; +# if (foo()) { +# } else { +# } +# enum X : int { A, B }; +# +# * ``BS_Stroustrup`` (in configuration: ``Stroustrup``) Like ``Attach``, but break before function definitions, ``catch``, and ``else``. +# +# .. parsed-literal:: +# +# try { +# foo(); +# } catch () { +# } +# void foo() { bar(); } +# class foo +# { +# }; +# if (foo()) { +# } else { +# } +# enum X : int +# { +# A, +# B +# }; +# +# * ``BS_Allman`` (in configuration: ``Allman``) Always break before braces. +# +# .. parsed-literal:: +# +# try { +# foo(); +# } +# catch () { +# } +# void foo() { bar(); } +# class foo { +# }; +# if (foo()) { +# } +# else { +# } +# enum X : int { A, B }; +# +# * ``BS_GNU`` (in configuration: ``GNU``) Always break before braces and add an extra level of indentation to braces of control statements, not to those of class, function or other definitions. +# +# .. parsed-literal:: +# +# try +# { +# foo(); +# } +# catch () +# { +# } +# void foo() { bar(); } +# class foo +# { +# }; +# if (foo()) +# { +# } +# else +# { +# } +# enum X : int +# { +# A, +# B +# }; +# +# * ``BS_WebKit`` (in configuration: ``WebKit``) Like ``Attach``, but break before functions. +# +# .. parsed-literal:: +# +# try { +# foo(); +# } catch () { +# } +# void foo() { bar(); } +# class foo { +# }; +# if (foo()) { +# } else { +# } +# enum X : int { A, B }; +# +# * ``BS_Custom`` (in configuration: ``Custom``) Configure each individual brace in *BraceWrapping*. +BreakBeforeBraces: Custom + +# **BreakBeforeInheritanceComma** (``bool``) +# If ``true``, in the class inheritance expression clang-format will break before ``:`` and ``,`` if there is multiple inheritance. +# +# true: false: +# class MyClass vs. class MyClass : public X, public Y { +# : public X }; +# , public Y { +# }; +BreakBeforeInheritanceComma: true + +# **BreakBeforeTernaryOperators** (``bool``) +# If ``true``, ternary operators will be placed after line breaks. +# +# true: +# veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription +# ? firstValue +# : SecondValueVeryVeryVeryVeryLong; +# +# false: +# veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription ? +# firstValue : +# SecondValueVeryVeryVeryVeryLong; +BreakBeforeTernaryOperators: true + +# **BreakConstructorInitializers** (``BreakConstructorInitializersStyle``) +# The constructor initializers style to use. +# +# Possible values: +# +# * ``BCIS_BeforeColon`` (in configuration: ``BeforeColon``) Break constructor initializers before the colon and after the commas. +# +# Constructor() +# : initializer1(), +# initializer2() +# +# * ``BCIS_BeforeComma`` (in configuration: ``BeforeComma``) Break constructor initializers before the colon and commas, and align the commas with the colon. +# +# Constructor() +# : initializer1() +# , initializer2() +# +# * ``BCIS_AfterColon`` (in configuration: ``AfterColon``) Break constructor initializers after the colon and commas. +# +# Constructor() : +# initializer1(), initializer2() +BreakConstructorInitializers: BeforeComma + +# **BreakStringLiterals** (``bool``) +# Allow breaking string literals when formatting. +BreakStringLiterals: false + +BreakInheritanceList: AfterColon + +# **ColumnLimit** (``unsigned``) +# The column limit. +# +# A column limit of ``0`` means that there is no column limit. In this case, clang-format will respect +# the input's line breaking decisions within statements unless they contradict other rules. +ColumnLimit: 140 + +# **CommentPragmas** (``std::string``) +# A regular expression that describes comments with special meaning, which should not be split into lines or otherwise changed. +# +# // CommentPragmas: '^ FOOBAR pragma:' +# // Will leave the following line unaffected +# #include // FOOBAR pragma: keep +CommentPragmas: '' + +# **CompactNamespaces** (``bool``) +# If ``true``, consecutive namespace declarations will be on the same line. If ``false``, each namespace is declared on a new line. +# +# true: +# namespace Foo { namespace Bar { +# }} +# +# false: +# namespace Foo { +# namespace Bar { +# } +# } +# +# If it does not fit on a single line, the overflowing namespaces get wrapped: +# +# namespace Foo { namespace Bar { +# namespace Extra { +# }}} +CompactNamespaces: true + +# **ConstructorInitializerAllOnOneLineOrOnePerLine** (``bool``) +# If the constructor initializers don't fit on a line, put each initializer on its own line. +# +# true: +# SomeClass\:\:Constructor() +# : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa) { +# return 0; +# } +# +# false: +# SomeClass\:\:Constructor() +# : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa), +# aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa) { +# return 0; +# } +ConstructorInitializerAllOnOneLineOrOnePerLine: true + +# **ConstructorInitializerIndentWidth** (``unsigned``) +# The number of characters to use for indentation of constructor initializer lists. +ConstructorInitializerIndentWidth: 4 + +# **ContinuationIndentWidth** (``unsigned``) +# Indent width for line continuations. +# +# ContinuationIndentWidth: 2 +# +# int i = // VeryVeryVeryVeryVeryLongComment +# longFunction( // Again a long comment +# arg); +ContinuationIndentWidth: 4 + +# **Cpp11BracedListStyle** (``bool``) +# If ``true``, format braced lists as best suited for C++11 braced lists. +# +# Important differences: - No spaces inside the braced list. - No line break before the closing brace. - Indentation with the continuation indent, not with the block indent. +# +# Fundamentally, C++11 braced lists are formatted exactly like function calls would be formatted in their place. +# If the braced list follows a name (e.g. a type or variable name), clang-format formats as if the ``{}`` were the parentheses of a function call with that name. If there is no name, a zero-length name is assumed. +# +# true: false: +# vector x{1, 2, 3, 4}; vs. vector x{ 1, 2, 3, 4 }; +# vector x{{}, {}, {}, {}}; vector x{ {}, {}, {}, {} }; +# f(MyMap[{composite, key}]); f(MyMap[{ composite, key }]); +# new int[3]{1, 2, 3}; new int[3]{ 1, 2, 3 }; +Cpp11BracedListStyle: true + +# **DerivePointerAlignment** (``bool``) +# If ``true``, analyze the formatted file for the most common alignment of ``&`` and ``*``. +# Pointer and reference alignment styles are going to be updated according to the preferences found in the file. ``PointerAlignment`` is then used only as fallback. +DerivePointerAlignment: true + +# **DisableFormat** (``bool``) +# Disables formatting completely. +DisableFormat: false + +# **ExperimentalAutoDetectBinPacking** (``bool``) +# If ``true``, clang-format detects whether function calls and definitions are formatted with one parameter per line. +# +# Each call can be bin-packed, one-per-line or inconclusive. If it is inconclusive, e.g. completely on one line, but a decision needs to be made, clang-format analyzes whether there are other bin-packed cases in the input file and act accordingly. +# +# NOTE: This is an experimental flag, that might go away or be renamed. Do not use this in config files, etc. Use at your own risk. +ExperimentalAutoDetectBinPacking: false + +# **FixNamespaceComments** (``bool``) +# If ``true``, clang-format adds missing namespace end comments and fixes invalid existing ones. +# +# true: false: +# namespace a { vs. namespace a { +# foo(); foo(); +# } // namespace a; } +FixNamespaceComments: true + +# **ForEachMacros** (``std::vector``) +# A vector of macros that should be interpreted as foreach loops instead of as function calls. +# +# These are expected to be macros of the form: +# +# FOREACH(, ...) +# +# +# In the .clang-format configuration file, this can be configured like: +# +# ForEachMacros: \['RANGES_FOR', 'FOREACH'] +# +# For example: BOOST_FOREACH. +ForEachMacros: [ ] + +# **IncludeBlocks** (``IncludeBlocksStyle``) +# Dependent on the value, multiple ``#include`` blocks can be sorted as one and divided based on category. +# +# Possible values: +# +# * ``IBS_Preserve`` (in configuration: ``Preserve``) Sort each ``#include`` block separately. +# +# .. parsed-literal:: +# +# #include "b.h" into #include "b.h" +# +# #include #include "a.h" +# #include "a.h" #include +# +# * ``IBS_Merge`` (in configuration: ``Merge``) Merge multiple ``#include`` blocks together and sort as one. +# +# .. parsed-literal:: +# +# #include "b.h" into #include "a.h" +# #include "b.h" +# #include #include +# #include "a.h" +# +# * ``IBS_Regroup`` (in configuration: ``Regroup``) Merge multiple ``#include`` blocks together and sort as one. Then split into groups based on category priority. See ``IncludeCategories``. +# +# .. parsed-literal:: +# +# #include "b.h" into #include "a.h" +# #include "b.h" +# #include +# #include "a.h" #include +IncludeBlocks: Preserve + +# **IncludeCategories** (``std::vector``) +# Regular expressions denoting the different ``#include`` categories used for ordering ``#includes``. +# +# These regular expressions are matched against the filename of an include (including the <> or "") in order. The value belonging to the first matching regular expression is assigned and ``#includes`` are sorted first according to increasing category number and then alphabetically within each category. +# +# If none of the regular expressions match, INT_MAX is assigned as category. The main header for a source file automatically gets category 0. so that it is generally kept at the beginning of the ``#includes`` (http://llvm.org/docs/CodingStandards.html#include-style). However, you can also assign negative priorities if you have certain headers that always need to be first. +# +# To configure this in the .clang-format file, use: +# +# IncludeCategories: +# - Regex: '^"(llvm|llvm-c|clang|clang-c)/' +# Priority: 2 +# - Regex: '^(<|"(gtest|gmock|isl|json)/)' +# Priority: 3 +# - Regex: '.*' +# Priority: 1 +IncludeCategories: + - Regex: '^".+"$' + Priority: 1 + - Regex: '^<(maps|yandex/maps)/.+>$' + Priority: 2 + - Regex: '^<(contrib|library|util)/.+>$' + Priority: 3 + - Regex: '^$' + Priority: 4 + - Regex: '^<.+(.h|.hpp)>$' + Priority: 5 + - Regex: '^<.+>$' + Priority: 6 + +# **IncludeIsMainRegex** (``std::string``) +# Specify a regular expression of suffixes that are allowed in the file-to-main-include mapping. +# +# When guessing whether a #include is the "main" include (to assign category 0, see above), use this regex of allowed suffixes to the header stem. A partial match is done, so that: - "" means "arbitrary suffix" - "$" means "no suffix" +# +# For example, if configured to "(_test)?$", then a header a.h would be seen as the "main" include in both a.cc and a_test.cc. +IncludeIsMainRegex: '$' + +# **IndentCaseLabels** (``bool``) +# Indent case labels one level from the switch statement. +# +# When ``false``, use the same indentation level as for the switch statement. Switch statement body is always indented one level more than case labels. +# +# false: true: +# switch (fool) { vs. switch (fool) { +# case 1: case 1: +# bar(); bar(); +# break; break; +# default: default: +# plop(); plop(); +# } } +IndentCaseLabels: false + +# **IndentPPDirectives** (``PPDirectiveIndentStyle``) +# The preprocessor directive indenting style to use. +# +# Possible values: +# +# * ``PPDIS_None`` (in configuration: ``None``) Does not indent any directives. +# +# .. parsed-literal:: +# +# #if FOO +# #if BAR +# #include +# #endif +# #endif +# +# * ``PPDIS_AfterHash`` (in configuration: ``AfterHash``) Indents directives after the hash. +# +# .. parsed-literal:: +# +# #if FOO +# # if BAR +# # include +# # endif +# #endif +IndentPPDirectives: None + +# **IndentWidth** (``unsigned``) +# The number of columns to use for indentation. +# +# IndentWidth: 3 +# +# void f() { +# someFunction(); +# if (true, false) { +# f(); +# } +# } +IndentWidth: 4 + +# **IndentWrappedFunctionNames** (``bool``) +# Indent if a function definition or declaration is wrapped after the type. +# +# true: +# LoooooooooooooooooooooooooooooooooooooooongReturnType +# LoooooooooooooooooooooooooooooooongFunctionDeclaration(); +# +# false: +# LoooooooooooooooooooooooooooooooooooooooongReturnType +# LoooooooooooooooooooooooooooooooongFunctionDeclaration(); +IndentWrappedFunctionNames: true + +# **KeepEmptyLinesAtTheStartOfBlocks** (``bool``) +# If true, the empty line at the start of blocks is kept. +# +# true: false: +# if (foo) { vs. if (foo) { +# bar(); +# bar(); } +# } +KeepEmptyLinesAtTheStartOfBlocks: false + +# **MacroBlockBegin** (``std::string``) +# A regular expression matching macros that start a block. +# +# # With: +# MacroBlockBegin: "^NS_MAP_BEGIN|\\ +# NS_TABLE_HEAD$" +# MacroBlockEnd: "^\\ +# NS_MAP_END|\\ +# NS_TABLE\_.*_END$" +# +# NS_MAP_BEGIN +# foo(); +# NS_MAP_END +# +# NS_TABLE_HEAD +# bar(); +# NS_TABLE_FOO_END +# +# # Without: +# NS_MAP_BEGIN +# foo(); +# NS_MAP_END +# +# NS_TABLE_HEAD +# bar(); +# NS_TABLE_FOO_END +MacroBlockBegin: '' + +# **MacroBlockEnd** (``std::string``) +# A regular expression matching macros that end a block. +MacroBlockEnd: '' + +# **MaxEmptyLinesToKeep** (``unsigned``) +# The maximum number of consecutive empty lines to keep. +# +# MaxEmptyLinesToKeep: 1 vs. MaxEmptyLinesToKeep: 0 +# int f() { int f() { +# int = 1; int i = 1; +# i = foo(); +# i = foo(); return i; +# } +# return i; +# } +MaxEmptyLinesToKeep: 1 + +# **NamespaceIndentation** (``NamespaceIndentationKind``) +# The indentation used for namespaces. +# +# Possible values: +# +# * ``NI_None`` (in configuration: ``None``) Don't indent in namespaces. +# +# .. parsed-literal:: +# +# namespace out { +# int i; +# namespace in { +# int i; +# } +# } +# +# * ``NI_Inner`` (in configuration: ``Inner``) Indent only in inner namespaces (nested in other namespaces). +# +# .. parsed-literal:: +# +# namespace out { +# int i; +# namespace in { +# int i; +# } +# } +# +# * ``NI_All`` (in configuration: ``All``) Indent in all namespaces. +# +# .. parsed-literal:: +# +# namespace out { +# int i; +# namespace in { +# int i; +# } +# } +# +NamespaceIndentation: None + +# **NamespaceMacros** (``std::vector``) +# A vector of macros which are used to open namespace blocks. +# +# These are expected to be macros of the form: +# +# NAMESPACE(, ...) { +# +# } +# +# For example: TESTSUITE +NamespaceMacros: [Y_UNIT_TEST_SUITE, Y_UNIT_TEST_SUITE_F] + +# **PenaltyBreakAssignment** (``unsigned``) +# The penalty for breaking around an assignment operator. +PenaltyBreakAssignment: 2 + +# **PenaltyBreakBeforeFirstCallParameter** (``unsigned``) +# The penalty for breaking a function call after ``call(``. +PenaltyBreakBeforeFirstCallParameter: 100 + +# **PenaltyBreakComment** (``unsigned``) +# The penalty for each line break introduced inside a comment. +PenaltyBreakComment: 1000 + +# **PenaltyBreakFirstLessLess** (``unsigned``) +# The penalty for breaking before the first ``<<``. +PenaltyBreakFirstLessLess: 120 + +# **PenaltyBreakString** (``unsigned``) +# The penalty for each line break introduced inside a string literal. +PenaltyBreakString: 1000 + +# **PenaltyExcessCharacter** (``unsigned``) +# The penalty for each character outside of the column limit. +PenaltyExcessCharacter: 12 + +# **PenaltyReturnTypeOnItsOwnLine** (``unsigned``) +# Penalty for putting the return type of a function onto its own line. +PenaltyReturnTypeOnItsOwnLine: 250 + +# **PointerAlignment** (``PointerAlignmentStyle``) +# Pointer and reference alignment style. +# +# Possible values: +# +# * ``PAS_Left`` (in configuration: ``Left``) Align pointer to the left. +# +# .. parsed-literal:: +# +# int* a; +# +# * ``PAS_Right`` (in configuration: ``Right``) Align pointer to the right. +# +# .. parsed-literal:: +# +# int \*a; +# +# * ``PAS_Middle`` (in configuration: ``Middle``) Align pointer in the middle. +# +# .. parsed-literal:: +# +# int * a; +PointerAlignment: Left + +# **RawStringFormats** (``std::vector``) +# Defines hints for detecting supported languages code blocks in raw strings. +# +# A raw string with a matching delimiter or a matching enclosing function name will be reformatted assuming the specified language based on the style for that language defined in the .clang-format file. If no style has been defined in the .clang-format file for the specific language, a predefined style given by 'BasedOnStyle' is used. If 'BasedOnStyle' is not found, the formatting is based on llvm style. A matching delimiter takes precedence over a matching enclosing function name for determining the language of the raw string contents. +# +# If a canonical delimiter is specified, occurrences of other delimiters for the same language will be updated to the canonical if possible. +# +# There should be at most one specification per language and each delimiter and enclosing function should not occur in multiple specifications. +# +# To configure this in the .clang-format file, use: +# +# RawStringFormats: +# - Language: TextProto +# Delimiters: +# - 'pb' +# - 'proto' +# EnclosingFunctions: +# - 'PARSE_TEXT_PROTO' +# BasedOnStyle: google +# - Language: Cpp +# Delimiters: +# - 'cc' +# - 'cpp' +# BasedOnStyle: llvm +# CanonicalDelimiter: 'cc' + +# Clang version >= 6. +#RawStringFormats: + +# **ReflowComments** (``bool``) +# If ``true``, clang-format will attempt to re-flow comments. +# +# false: +# // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information +# /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information \*/ +# +# true: +# // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of +# // information +# /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of +# * information \*/ +ReflowComments: false + +# **SortIncludes** (``bool``) +# If ``true``, clang-format will sort ``#includes``. +# +# false: true: +# #include "b.h" vs. #include "a.h" +# #include "a.h" #include "b.h" +SortIncludes: false + +# **SortUsingDeclarations** (``bool``) +# If ``true``, clang-format will sort using declarations. +# +# The order of using declarations is defined as follows: Split the strings by "\:\:" and discard any initial empty strings. The last element of each list is a non-namespace name; all others are namespace names. Sort the lists of names lexicographically, where the sort order of individual names is that all non-namespace names come before all namespace names, and within those groups, names are in case-insensitive lexicographic order. +# +# false: true: +# using std::cout; vs. using std::cin; +# using std::cin; using std::cout; +SortUsingDeclarations: true + +# **SpaceAfterCStyleCast** (``bool``) +# If ``true``, a space is inserted after C style casts. +# +# true: false: +# (int) i; vs. (int)i; +SpaceAfterCStyleCast: false + +# **SpaceAfterTemplateKeyword** (``bool``) +# If ``true``, a space will be inserted after the 'template' keyword. +# +# true: false: +# template void foo(); vs. template void foo(); +SpaceAfterTemplateKeyword: false + +# **SpaceBeforeAssignmentOperators** (``bool``) +# If ``false``, spaces will be removed before assignment operators. +# +# true: false: +# int a = 5; vs. int a=5; +# a += 42 a+=42; +SpaceBeforeAssignmentOperators: true + +SpaceBeforeCpp11BracedList: false + +# **SpaceBeforeCtorInitializerColon** (``bool``) +# If ``false``, spaces will be removed before constructor initializer colon. +# +# true: false: +# Foo::Foo() : a(a) {} Foo::Foo(): a(a) {} +SpaceBeforeCtorInitializerColon: true + +# **SpaceBeforeInheritanceColon** (``bool``) +# If ``false``, spaces will be removed before inheritance colon. +# +# true: false: +# class Foo : Bar {} vs. class Foo: Bar {} +SpaceBeforeInheritanceColon: true + +# **SpaceBeforeParens** (``SpaceBeforeParensOptions``) +# Defines in which cases to put a space before opening parentheses. +# +# Possible values: +# +# * ``SBPO_Never`` (in configuration: ``Never``) Never put a space before opening parentheses. +# +# .. parsed-literal:: +# +# void f() { +# if(true) { +# f(); +# } +# } +# +# * ``SBPO_ControlStatements`` (in configuration: ``ControlStatements``) Put a space before opening parentheses only after control statement keywords (``for/if/while...``). +# +# .. parsed-literal:: +# +# void f() { +# if (true) { +# f(); +# } +# } +# +# * ``SBPO_Always`` (in configuration: ``Always``) Always put a space before opening parentheses, except when it's prohibited by the syntax rules (in function-like macro definitions) or when determined by other style rules (after unary operators, opening parentheses, etc.) +# +# .. parsed-literal:: +# +# void f () { +# if (true) { +# f (); +# } +# } +# +SpaceBeforeParens: ControlStatements + +# **SpaceBeforeRangeBasedForLoopColon** (``bool``) +# If ``false``, spaces will be removed before range-based for loop colon. +# +# true: false: +# for (auto v : values) {} vs. for(auto v: values) {} +SpaceBeforeRangeBasedForLoopColon: false + +# **SpaceInEmptyParentheses** (``bool``) +# If ``true``, spaces may be inserted into ``()``. +# +# true: false: +# void f( ) { vs. void f() { +# int x[] = {foo( ), bar( )}; int x[] = {foo(), bar()}; +# if (true) { if (true) { +# f( ); f(); +# } } +# } } +SpaceInEmptyParentheses: false + +# **SpacesBeforeTrailingComments** (``unsigned``) +# The number of spaces before trailing line comments (``//`` - comments). +# +# This does not affect trailing block comments (``/*`` - comments) as those commonly have different usage patterns and a number of special cases. +# +# SpacesBeforeTrailingComments: 3 +# void f() { +# if (true) { // foo1 +# f(); // bar +# } // foo +# } +SpacesBeforeTrailingComments: 1 + +# **SpacesInAngles** (``bool``) +# If ``true``, spaces will be inserted after ``<`` and before ``>`` in template argument lists. +# +# true: false: +# static_cast< int >(arg); vs. static_cast(arg); +# std\:\:function< void(int) > fct; std\:\:function fct; +SpacesInAngles: false + +# **SpacesInContainerLiterals** (``bool``) +# If ``true``, spaces are inserted inside container literals (e.g. ObjC and Javascript array and dict literals). +# +# true: false: +# var arr = [ 1, 2, 3 ]; vs. var arr = [1, 2, 3]; +# f({a : 1, b : 2, c : 3}); f({a: 1, b: 2, c: 3}); +SpacesInContainerLiterals: true + +# **SpacesInCStyleCastParentheses** (``bool``) +# If ``true``, spaces may be inserted into C style casts. +# +# true: false: +# x = ( int32 )y vs. x = (int32)y +SpacesInCStyleCastParentheses: false + +# **SpacesInParentheses** (``bool``) +# If ``true``, spaces will be inserted after ``(`` and before ``)``. +# +# true: false: +# t f( Deleted & ) & = delete; vs. t f(Deleted &) & = delete; +SpacesInParentheses: false + +# **SpacesInSquareBrackets** (``bool``) +# If ``true``, spaces will be inserted after ``[`` and before ``]``. Lambdas or unspecified size array declarations will not be affected. +# +# true: false: +# int a[ 5 ]; vs. int a[5]; +# std::unique_ptr foo() {} // Won't be affected +SpacesInSquareBrackets: false + +# **Standard** (``LanguageStandard``) +# Format compatible with this standard, e.g. use ``A >`` instead of ``A>`` for ``LS_Cpp03``. +# +# Possible values: +# +# * ``LS_Cpp03`` (in configuration: ``Cpp03``) Use C++03-compatible syntax. +# * ``LS_Cpp11`` (in configuration: ``Cpp11``) Use features of C++11, C++14 and C++1z (e.g. ``A>`` instead of ``A >``). +# * ``LS_Auto`` (in configuration: ``Auto``) Automatic detection based on the input. +Standard: Cpp11 + +# **TabWidth** (``unsigned``) +# The number of columns used for tab stops. +TabWidth: 4 + +# **UseTab** (``UseTabStyle``) +# The way to use tab characters in the resulting file. +# +# Possible values: +# +# * ``UT_Never`` (in configuration: ``Never``) Never use tab. +# * ``UT_ForIndentation`` (in configuration: ``ForIndentation``) Use tabs only for indentation. +# * ``UT_ForContinuationAndIndentation`` (in configuration: ``ForContinuationAndIndentation``) Use tabs only for line continuation and indentation. +# * ``UT_Always`` (in configuration: ``Always``) Use tabs whenever we need to fill whitespace that spans at least from one tab stop to the next one. +UseTab: Never diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..2a7ae76 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,175 @@ +CheckOptions: +- key: readability-identifier-naming.ClassCase + value: CamelCase +- key: readability-identifier-naming.ParameterCase + value: camelBack +- key: readability-identifier-naming.ClassMethodCase + value: lower_case +- key: readability-identifier-naming.FunctionCase + value: lower_case +- key: readability-identifier-naming.EnumConstantCase + value: CamelCase +- key: readability-identifier-naming.LocalVariableCase + value: camelBack +- key: readability-identifier-naming.PrivateMemberSuffix + value: _ +- key: readability-identifier-naming.EnumCase + value: CamelCase +- key: readability-identifier-naming.GlobalVariableCase + value: camelBack +- key: readability-identifier-naming.LocalConstantCase + value: aNy_CasE +- key: readability-identifier-naming.ProtectedMemberSuffix + value: _ +- key: readability-identifier-naming.ClassMemberCase + value: camelBack +- key: readability-identifier-naming.MacroDefinitionCase + value: UPPER_CASE +- key: readability-identifier-naming.GlobalVariablePrefix + value: g_ +- key: readability-identifier-naming.GlobalConstantCase + value: UPPER_CASE +- key: performance-move-const-arg.CheckTriviallyCopyableMove + value: false +Checks: '-*, + -bugprone-argument-comment, + -bugprone-branch-clone, + -bugprone-exception-escape, + -bugprone-infinite-loop, + -bugprone-lambda-function-name, + -bugprone-macro-parentheses, + -bugprone-narrowing-conversions, + -bugprone-reserved-identifier, + -bugprone-signed-char-misuse, + -bugprone-string-integer-assignment, + -bugprone-suspicious-include, + -bugprone-use-after-move, + -cppcoreguidelines-avoid-c-arrays, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-explicit-virtual-functions, + -cppcoreguidelines-init-variables, + -cppcoreguidelines-interfaces-global-init, + -cppcoreguidelines-macro-usage, + -cppcoreguidelines-narrowing-conversions, + -cppcoreguidelines-no-malloc, + -cppcoreguidelines-non-private-member-variables-in-classes, + -cppcoreguidelines-owning-memory, + -cppcoreguidelines-pro-bounds-array-to-pointer-decay, + -cppcoreguidelines-pro-bounds-constant-array-index, + -cppcoreguidelines-pro-bounds-pointer-arithmetic, + -cppcoreguidelines-pro-type-const-cast, + -cppcoreguidelines-pro-type-cstyle-cast, + -cppcoreguidelines-pro-type-member-init, + -cppcoreguidelines-pro-type-reinterpret-cast, + -cppcoreguidelines-pro-type-static-cast-downcast, + -cppcoreguidelines-pro-type-union-access, + -cppcoreguidelines-pro-type-vararg, + -cppcoreguidelines-special-member-functions, + -fuchsia-statically-constructed-objects, + -llvm-namespace-comment, + -misc-definitions-in-headers, + -modernize-avoid-bind, + -modernize-concat-nested-namespaces, + -modernize-deprecated-headers, + -modernize-loop-convert, + -modernize-make-shared, + -modernize-make-unique, + -modernize-pass-by-value, + -modernize-raw-string-literal, + -modernize-use-auto, + -modernize-use-default-member-init, + -modernize-use-emplace, + -modernize-use-equals-default, + -modernize-use-equals-delete, + -modernize-use-nodiscard, + -modernize-use-nullptr, + -modernize-use-using, + -performance-faster-string-find, + -performance-for-range-copy, + -performance-implicit-conversion-in-loop, + -performance-inefficient-algorithm, + -performance-inefficient-string-concatenation, + -performance-inefficient-vector-operation, + -performance-move-const-arg, + -performance-move-constructor-init, + -performance-no-automatic-move, + -performance-no-int-to-ptr, + -performance-noexcept-move-constructor, + -performance-trivially-destructible, + -performance-type-promotion-in-math-fn, + -performance-unnecessary-copy-initialization, + -performance-unnecessary-value-param, + -portability-restrict-system-includes, + -portability-simd-intrinsics, + -readability-avoid-const-params-in-decls, + -readability-braces-around-statements, + -readability-const-return-type, + -readability-container-size-empty, + -readability-convert-member-functions-to-static, + -readability-deleted-default, + -readability-else-after-return, + -readability-function-cognitive-complexity, + -readability-function-size, + -readability-identifier-naming, + -readability-implicit-bool-conversion, + -readability-inconsistent-declaration-parameter-name, + -readability-isolate-declaration, + -readability-magic-numbers, + -readability-make-member-function-const, + -readability-named-parameter, + -readability-non-const-parameter, + -readability-qualified-auto, + -readability-redundant-access-specifiers, + -readability-redundant-control-flow, + -readability-redundant-declaration, + -readability-redundant-member-init, + -readability-redundant-smartptr-get, + -readability-redundant-string-cstr, + -readability-redundant-string-init, + -readability-simplify-boolean-expr, + -readability-static-accessed-through-instance, + -readability-static-definition-in-anonymous-namespace, + -readability-uppercase-literal-suffix, + -readability-use-anyofallof, + bugprone-branch-clone, + bugprone-infinite-loop, + bugprone-lambda-function-name, + bugprone-macro-parentheses, + bugprone-reserved-identifier, + bugprone-string-integer-assignment, + cppcoreguidelines-init-variables, + cppcoreguidelines-no-malloc, + cppcoreguidelines-pro-type-member-init, + misc-definitions-in-headers, + modernize-concat-nested-namespaces, + modernize-make-shared, + modernize-make-unique, + modernize-pass-by-value, + modernize-use-default-member-init, + modernize-use-emplace, + modernize-use-equals-default, + modernize-use-equals-delete, + modernize-use-using, + llvm-namespace-comment, + performance-faster-string-find, + performance-for-range-copy, + performance-inefficient-algorithm, + performance-move-const-arg, + performance-move-constructor-init, + performance-no-automatic-move, + performance-noexcept-move-constructor, + performance-unnecessary-copy-initialization, + performance-unnecessary-value-param, + readability-avoid-const-params-in-decls, + readability-convert-member-functions-to-static, + readability-const-return-type, + readability-identifier-naming, + readability-inconsistent-declaration-parameter-name, + readability-make-member-function-const, + readability-redundant-declaration, + readability-static-definition-in-anonymous-namespace, + arcadia-typeid-name-restriction, + bugprone-use-after-move, + performance-implicit-conversion-in-loop, + readability-identifier-naming' diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..cf8f0d3 --- /dev/null +++ b/.clangd @@ -0,0 +1,3 @@ +CompileFlags: + Add: [-D_CLANGD=1, /std:c++20] + CompilationDatabase: _build/ diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..01f41c6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*.{as,cpp,h,hpp,inl,txt}] +charset = utf-8-bom +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e88bfcc --- /dev/null +++ b/.gitattributes @@ -0,0 +1,28 @@ +* text=auto +*.htm text eol=crlf +*.html text eol=crlf +renames.txt text eol=crlf + +*.v text eol=lf +*.as text eol=lf +*.cpp text eol=lf +*.h text eol=lf +*.js text eol=lf + +*.feature text +*.md text +*.json text eol=lf + +*.bat text eol=crlf +*.cmd text eol=crlf +*.ps1 text eol=crlf + +*.sh text eol=lf +*.groovy text eol=lf + +# Archives +# 1C +*.xml text eol=crlf + +*.bsl text eol=crlf +*.os text eol=crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0e7ca05 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +_build/ +build/ +out/ +!.gitignore +*.ipch +*.VC.* +.vs/ +.vscode/ +CMakeUserPresets.json diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..4433891 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ThirdParty/simdutf"] + path = ThirdParty/simdutf + url = https://github.com/simdutf/simdutf.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..9df8af1 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,90 @@ +cmake_minimum_required (VERSION 3.20) +include(CMakeDependentOption) + +project ("simstr") +set (CMAKE_CXX_STANDARD 20) + +if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) + set (MSVC_COMPILER ON) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8 /Zc:strictStrings") +elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL Clang) + set (CLANG_COMPILER ON) +endif () + +option(SIMSTR_BUILD_TESTS "Построить тесты" ON) +option(SIMSTR_BENCHMARKS "Построить замеры производительности" ON) +option(SIMSTR_SHARED "Функции simstr должны экспортироваться или импортироваться" OFF) + +if (EMSCRIPTEN) + option(SIMSTR_EMSCRIPTEN_MT "Использовать многопоточность в Emscripten" OFF) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-warn-absolute-paths -Wno-unknown-warning-option -msimd128 -msse4.2 -msse3") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-warn-absolute-paths -Wno-unknown-warning-option -msimd128 -msse4.2 -msse3") + + if (SIMSTR_EMSCRIPTEN_MT) + message("Build MT emscripten") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread -sPTHREAD_POOL_SIZE=navigator.hardwareConcurrency-1") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sENVIRONMENT=web,worker") + endif() +endif(EMSCRIPTEN) + +set (SIMDUTF_TOOLS OFF) +set (SIMDUTF_TESTS OFF) +add_subdirectory(ThirdParty/simdutf) + +include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include") + +add_library(simstr + src/sstring.cpp + src/simple_unicode.cpp +) + +target_link_libraries(simstr PUBLIC simdutf) + +if (SIMSTR_SHARED) + add_compile_definitions(SIMSTR_SHARED) + target_compile_definitions(simstr PRIVATE SIMSTR_EXPORT) +endif(SIMSTR_SHARED) + +if (SIMSTR_BUILD_TESTS) + enable_testing() + set (BUILD_TESTS ON) + # Load and build GTest + include(FetchContent) + FetchContent_Declare( + googletest + # Specify the commit you depend on and update it regularly. + URL https://github.com/google/googletest/archive/refs/tags/release-1.12.1.zip + ) + + # For Windows: Prevent overriding the parent project's compiler/linker settings + set(gtest_force_shared_crt FALSE CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(googletest) + add_subdirectory(tests) +endif() + +function (GBencmark) + # Load and build Google benchmarks + include(FetchContent) + FetchContent_Declare( + googlebench + # Specify the commit you depend on and update it regularly. + URL https://github.com/google/benchmark/archive/refs/tags/v1.7.0.zip + ) + set (CMAKE_CXX_STANDARD 20) + set (BENCHMARK_ENABLE_TESTING OFF) + set (BENCHMARK_ENABLE_LTO OFF) + set (BENCHMARK_ENABLE_INSTALL OFF) + set (BENCHMARK_INSTALL_DOCS OFF) + set (BENCHMARK_DOWNLOAD_DEPENDENCIES ON) + set (BENCHMARK_ENABLE_GTEST_TESTS OFF) + add_compile_definitions(BENCHMARK_STATIC_DEFINE) + FetchContent_MakeAvailable(googlebench) +endfunction() + +if (SIMSTR_BENCHMARKS)# AND CMAKE_BUILD_TYPE STREQUAL Release) + set (BUILD_BENCHMARKS ON) + GBencmark() + add_subdirectory(bench) +endif () diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..59e0661 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,191 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "base", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/_build/objs/${presetName}", + "installDir": "${sourceDir}/_build/install/${presetName}", + "cacheVariables": { + "CMAKE_EXPORT_COMPILE_COMMANDS": true + } + }, + { + "name": "windows-base", + "hidden": true, + "inherits": "base", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + }, + { + "name": "compiler-cl", + "hidden": true, + "cacheVariables": { + "CMAKE_C_COMPILER": "cl", + "CMAKE_CXX_COMPILER": "cl" + } + }, + { + "name": "compiler-clang-cl", + "hidden": true, + "cacheVariables": { + "CMAKE_C_COMPILER": "clang-cl", + "CMAKE_CXX_COMPILER": "clang-cl" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "intelliSenseMode": "windows-clang-x64" + } + } + }, + { + "name": "x64", + "hidden": true, + "architecture": { + "value": "x64", + "strategy": "external" + } + }, + { + "name": "x86", + "hidden": true, + "architecture": { + "value": "x86", + "strategy": "external" + } + }, + { + "name": "windows-base-debug", + "hidden": true, + "inherits": "windows-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "windows-base-release", + "hidden": true, + "inherits": "windows-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "x64-debug", + "displayName": "x64 Debug", + "inherits": [ + "windows-base-debug", + "compiler-cl", + "x64" + ] + }, + { + "name": "x64-release", + "displayName": "x64 Release", + "inherits": [ + "windows-base-release", + "compiler-cl", + "x64" + ] + }, + { + "name": "x64-debug-clang", + "displayName": "clang x64 Debug", + "inherits": [ + "windows-base-debug", + "compiler-clang-cl", + "x64" + ] + }, + { + "name": "x64-release-clang", + "displayName": "clang x64 Release", + "inherits": [ + "windows-base-release", + "compiler-clang-cl", + "x64" + ] + }, + { + "name": "x86-debug", + "displayName": "x86 Debug", + "inherits": [ + "windows-base-debug", + "compiler-cl", + "x86" + ] + }, + { + "name": "x86-release", + "displayName": "x86 Release", + "inherits": [ + "windows-base-release", + "compiler-cl", + "x86" + ] + }, + { + "name": "linux-base", + "hidden": true, + "inherits": "base", + "displayName": "Linux base", + "cacheVariables": { + "CMAKE_C_COMPILER": "gcc-13", + "CMAKE_CXX_COMPILER": "g++-13", + "CMAKE_EXPORT_COMPILE_COMMANDS": true + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Linux" + }, + "vendor": { + "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { + "sourceDir": "$env{HOME}/projects/from_win/$ms{projectDirName}", + "copySourcesOptions": { + "exclusionList": [ + ".vs", + ".git", + "out", + "_build", + "build", + "1C" + ] + } + } + } + }, + { + "name": "linux-debug", + "displayName": "Linux Debug", + "inherits": "linux-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "linux-release", + "displayName": "Linux Release", + "inherits": "linux-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "linux-release-clang", + "displayName": "Linux Release Clang", + "inherits": "linux-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_C_COMPILER": "clang-21", + "CMAKE_CXX_COMPILER": "clang++-21" + } + } + ], + "buildPresets": [ + ] +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..017b746 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 orefkov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ThirdParty/simdutf b/ThirdParty/simdutf new file mode 160000 index 0000000..dd192d6 --- /dev/null +++ b/ThirdParty/simdutf @@ -0,0 +1 @@ +Subproject commit dd192d6fc5fdf0ad21c0759cd3133bbcc7ae4122 diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt new file mode 100644 index 0000000..7932b20 --- /dev/null +++ b/bench/CMakeLists.txt @@ -0,0 +1,16 @@ +# CMakeList.txt : CMake project for core_as, include source and define +# project specific logic here. +# +cmake_minimum_required (VERSION 3.15) + +add_executable(benchStr bench_str.cpp bench.h) +target_link_libraries(benchStr simstr benchmark::benchmark benchmark::benchmark_main) + +add_executable(process_result process_result.cpp) +target_link_libraries(process_result simstr) + +if (EMSCRIPTEN) + #target_link_options(benchStr PRIVATE -sSTACK_SIZE=1048576 -sINITIAL_MEMORY=128MB -sALLOW_MEMORY_GROWTH=0) + set_target_properties (benchStr PROPERTIES SUFFIX .html) + target_link_options(benchStr PUBLIC --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/bench.js) +endif(EMSCRIPTEN) diff --git a/bench/bench.h b/bench/bench.h new file mode 100644 index 0000000..5c84925 --- /dev/null +++ b/bench/bench.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include + +#if defined(_MSC_VER) || (defined(__clang__) && __has_declspec_attribute(dllexport)) +#define BENCH_EXPORT __declspec(dllexport) +#elif (defined(__GNUC__) || defined(__GNUG__)) && defined(COREAS_EXPORTS) +#define BENCH_EXPORT __attribute__((visibility("default"))) +#else +#define BENCH_EXPORT +#endif diff --git a/bench/bench.js b/bench/bench.js new file mode 100644 index 0000000..f0a607a --- /dev/null +++ b/bench/bench.js @@ -0,0 +1 @@ +Module.arguments=['--benchmark_repetitions=10', '--benchmark_report_aggregates_only=true']; diff --git a/bench/bench_str.cpp b/bench/bench_str.cpp new file mode 100644 index 0000000..005f5c1 --- /dev/null +++ b/bench/bench_str.cpp @@ -0,0 +1,1906 @@ +/* + * (c) Проект "SimStr", Александр Орефков orefkov@gmail.com + * Бенчмарки + */ + +#include "bench.h" +#include +#include + +using namespace simstr; +using namespace std::literals; + +#define TEST_TEXT "Test text" +#define LONG_TEXT "123456789012345678901234567890" +#define TEXT_16 "abbaabbaabbaabba" + +#define CHECK_RESULT + +void __(benchmark::State& state) { for (auto _: state) {} } + +template +void CreateEmpty(benchmark::State& state) { + for (auto _: state) { + T empty_string; + benchmark::DoNotOptimize(empty_string); + } +} +BENCHMARK(__)->Name("----- Create Empty Str ---------")->Repetitions(1); +BENCHMARK(CreateEmpty) ->Name("std::string e;"); +BENCHMARK(CreateEmpty) ->Name("std::string_view e;"); +BENCHMARK(CreateEmpty) ->Name("ssa e;"); +BENCHMARK(CreateEmpty) ->Name("stringa e;"); +BENCHMARK(CreateEmpty>) ->Name("lstringa<20> e;"); +BENCHMARK(CreateEmpty>) ->Name("lstringa<40> e;"); + +template +void CreateShortLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string = TEST_TEXT; + benchmark::DoNotOptimize(empty_string); + } +} +BENCHMARK(__)->Name("----- Create Str from short literal (9 symbols) --------")->Repetitions(1); +BENCHMARK(CreateShortLiteral) ->Name("std::string e = \"Test text\";"); +BENCHMARK(CreateShortLiteral) ->Name("std::string_view e = \"Test text\";"); +BENCHMARK(CreateShortLiteral) ->Name("ssa e = \"Test text\";"); +BENCHMARK(CreateShortLiteral) ->Name("stringa e = \"Test text\";"); +BENCHMARK(CreateShortLiteral>) ->Name("lstringa<20> e = \"Test text\";"); +BENCHMARK(CreateShortLiteral>) ->Name("lstringa<40> e = \"Test text\";"); + +template +void CreateLongLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string{LONG_TEXT}; + benchmark::DoNotOptimize(empty_string); + } +} +BENCHMARK(__)->Name("----- Create Str from long literal (30 symbols) ---------")->Repetitions(1); +BENCHMARK(CreateLongLiteral) ->Name("std::string e = \"123456789012345678901234567890\";"); +BENCHMARK(CreateLongLiteral) ->Name("std::string_view e = \"123456789012345678901234567890\";"); +BENCHMARK(CreateLongLiteral) ->Name("ssa e = \"123456789012345678901234567890\";"); +BENCHMARK(CreateLongLiteral) ->Name("stringa e = \"123456789012345678901234567890\";"); +BENCHMARK(CreateLongLiteral>) ->Name("lstringa<20> e = \"123456789012345678901234567890\";"); +BENCHMARK(CreateLongLiteral>) ->Name("lstringa<40> e = \"123456789012345678901234567890\";"); + +template +void CopyShortString(benchmark::State& state) { + T x{TEST_TEXT}; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} +BENCHMARK(__)->Name("----- Create copy of Str with 9 symbols ---------")->Repetitions(1); +BENCHMARK(CopyShortString) ->Name("std::string e = \"Test text\"; auto c{e};"); +BENCHMARK(CopyShortString) ->Name("std::string_view e = \"Test text\"; auto c{e};"); +BENCHMARK(CopyShortString) ->Name("ssa e = \"Test text\"; auto c{e};"); +BENCHMARK(CopyShortString) ->Name("stringa e = \"Test text\"; auto c{e};"); +BENCHMARK(CopyShortString>) ->Name("lstringa<20> e = \"Test text\"; auto c{e};"); +BENCHMARK(CopyShortString>) ->Name("lstringa<40> e = \"Test text\"; auto c{e};"); + +template +void CopyLongString(benchmark::State& state) { + T x = LONG_TEXT; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + } +} + +BENCHMARK(__)->Name("----- Create copy of Str with 30 symbols ---------")->Repetitions(1); +BENCHMARK(CopyLongString) ->Name("std::string e = \"123456789012345678901234567890\"; auto c{e};"); +BENCHMARK(CopyLongString) ->Name("std::string_view e = \"123456789012345678901234567890\"; auto c{e};"); +BENCHMARK(CopyLongString) ->Name("ssa e = \"123456789012345678901234567890\"; auto c{e};"); +BENCHMARK(CopyLongString) ->Name("stringa e = \"123456789012345678901234567890\"; auto c{e};"); +BENCHMARK(CopyLongString>) ->Name("lstringa<20> e = \"123456789012345678901234567890\"; auto c{e};"); +BENCHMARK(CopyLongString>) ->Name("lstringa<40> e = \"123456789012345678901234567890\"; auto c{e};"); + +template +void Find(benchmark::State& state) { + T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT}; + for (auto _: state) { + int i = (int)x.find(TEST_TEXT); + #ifdef CHECK_RESULT + if (i != 90) { + state.SkipWithError("not find?"); + break; + } + #endif + benchmark::DoNotOptimize(i); + benchmark::DoNotOptimize(x); + } +} +BENCHMARK(__)->Name("----- Find 9 symbols text in end of 99 symbols text ---------")->Repetitions(1); +BENCHMARK(Find) ->Name("std::string::find;"); +BENCHMARK(Find) ->Name("std::string_view::find;"); +BENCHMARK(Find) ->Name("ssa::find;"); +BENCHMARK(Find) ->Name("stringa::find;"); +BENCHMARK(Find>) ->Name("lstringa<20>::find;"); +BENCHMARK(Find>) ->Name("lstringa<40>::find;"); + +template +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} +BENCHMARK(__)->Name("------- Copy not literal Str with N symbols ---------")->Repetitions(1); +BENCHMARK(CopyDynString) ->Name("std::string copy{str_with_len_N};")->Arg(15)->Arg(16)->Arg(23)->Arg(24)->RangeMultiplier(2)->Range(32, 4096); +BENCHMARK(CopyDynString) ->Name("stringa copy{str_with_len_N};")->Arg(15)->Arg(16)->Arg(23)->Arg(24)->RangeMultiplier(2)->Range(32, 4096); +BENCHMARK(CopyDynString>) ->Name("lstringa<16> copy{str_with_len_N};")->Arg(15)->Arg(16)->Arg(23)->Arg(24)->RangeMultiplier(2)->Range(32, 4096); +BENCHMARK(CopyDynString>) ->Name("lstringa<512> copy{str_with_len_N};")->Arg(15)->Arg(16)->Arg(23)->Arg(24)->RangeMultiplier(2)->Range(32, 4096); + +void ToIntStr10(benchmark::State& state, const std::string& s, int c) { + for (auto _: state) { + int res = std::strtol(s.c_str(), nullptr, 10); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(s); + } +} + +void ToIntStr16(benchmark::State& state, const std::string& s, int c) { + for (auto _: state) { + int res = std::strtol(s.c_str(), nullptr, 16); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(s); + } +} + +void ToIntStr0(benchmark::State& state, const std::string& s, int c) { + for (auto _: state) { + int res = std::strtol(s.c_str(), nullptr, 0); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(s); + } +} + +void ToIntFromChars10(benchmark::State& state, const std::string_view& s, int c) { +#ifdef __EMSCRIPTEN__ + state.SkipWithError("not implemented"); +#else + for (auto _: state) { + int res = 0; + std::from_chars(s.data(), s.data() + s.size(), res, 10); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(s); + } +#endif +} + +void ToIntFromChars16(benchmark::State& state, const std::string_view& s, int c) { +#ifdef __EMSCRIPTEN__ + state.SkipWithError("not implemented"); +#else + for (auto _: state) { + int res = 0; + std::from_chars(s.data(), s.data() + s.size(), res, 16); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(s); + } +#endif +} + +template +void ToIntSimStr10(benchmark::State& state, T t, int c) { + for (auto _: state) { + int res = std::get<0>(t. template to_int()); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(t); + } +} + +template +void ToIntSimStr16(benchmark::State& state, T t, int c) { + for (auto _: state) { + int res = std::get<0>(t. template to_int()); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(t); + } +} + +template +void ToIntSimStr0(benchmark::State& state, T t, int c) { + for (auto _: state) { + int res = std::get<0>(t. template to_int()); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(t); + } +} + +void ToIntNoOverflow(benchmark::State& state, ssa t, int c) { + for (auto _: state) { + int res = std::get<0>(t.to_int()); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(t); + } +} + +BENCHMARK(__)->Name("----- Convert to int '1234567' ---------")->Repetitions(1); +BENCHMARK_CAPTURE(ToIntStr10, , std::string{"123456789"}, 123456789) ->Name("std::string s = \"123456789\"; int res = std::strtol(s.c_str(), 0, 10);"); +BENCHMARK_CAPTURE(ToIntFromChars10, , std::string_view{"123456789"}, 123456789) ->Name("std::string_view s = \"123456789\"; std::from_chars(s.data(), s.data() + s.size(), res, 10);"); +BENCHMARK_CAPTURE(ToIntSimStr10, , stringa{"123456789"}, 123456789) ->Name("stringa s = \"123456789\"; int res = s.to_int"); +BENCHMARK_CAPTURE(ToIntSimStr10, , ssa{"123456789"}, 123456789) ->Name("ssa s = \"123456789\"; int res = s.to_int"); +BENCHMARK_CAPTURE(ToIntSimStr10, , lstringa<20>{"123456789"}, 123456789) ->Name("lstringa<20> s = \"123456789\"; int res = s.to_int"); +BENCHMARK(__)->Name("----- Convert to unsigned 'abcDef' ---------")->Repetitions(1); +BENCHMARK_CAPTURE(ToIntStr16, , std::string{"abcDef"}, 0xabcDef) ->Name("std::string s = \"abcDef\"; int res = std::strtol(s.c_str(), 0, 16);"); +BENCHMARK_CAPTURE(ToIntFromChars16, , std::string_view{"abcDef"}, 0xabcDef) ->Name("std::string_view s = \"abcDef\"; std::from_chars(s.data(), s.data() + s.size(), res, 16);"); +BENCHMARK_CAPTURE(ToIntSimStr16, , stringa{"abcDef"}, 0xabcDef) ->Name("stringa s = \"abcDef\"; int res = s.to_int"); +BENCHMARK_CAPTURE(ToIntSimStr16, , ssa{"abcDef"}, 0xabcDef) ->Name("ssa s = \"abcDef\"; int res = s.to_int"); +BENCHMARK_CAPTURE(ToIntSimStr16, >, lstringa<20>{"abcDef"}, 0xabcDef) ->Name("lstringa<20> s = \"abcDef\"; int res = s.to_int"); +BENCHMARK(__)->Name("----- Convert to int ' 1234567' ---------")->Repetitions(1); +BENCHMARK_CAPTURE(ToIntStr0, , std::string{" 123456789"}, 123456789) ->Name("std::string s = \" 123456789\"; int res = std::strtol(s.c_str(), 0, 0);"); +BENCHMARK_CAPTURE(ToIntSimStr0, , stringa{" 123456789"}, 123456789) ->Name("stringa s = \" 123456789\"; int res = s.to_int; // Check overflow"); +BENCHMARK_CAPTURE(ToIntNoOverflow, , ssa{" 123456789"}, 123456789) ->Name("ssa s = \" 123456789\"; int res = s.to_int; // No check overflow"); + +void AppendStreamConstLiteral(benchmark::State& state) { + for (auto _: state) { + std::string result; + std::stringstream str; + for (size_t c = 0; c < 64; c++) { + str << TEXT_16; + } + result = str.str(); + #ifdef CHECK_RESULT + if (result.size() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(str); + } +} + +void AppendStdStringConstLiteral(benchmark::State& state) { + for (auto _: state) { + std::string result; + for (size_t c = 0; c < 64; c++) { + result += TEXT_16; + } + #ifdef CHECK_RESULT + if (result.size() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + } +} + +template +void AppendLstringConstLiteral(benchmark::State& state) { + for (auto _: state) { + lstringa result; + for (size_t c = 0; c < 64; c++) { + result += TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + } +} + +BENCHMARK(__)->Name("-- Append const literal of 16 bytes 64 times, 1024 total length --")->Repetitions(1); +BENCHMARK(AppendStreamConstLiteral) ->Name("std::stringstream str; ... str << \"abbaabbaabbaabba\";"); +BENCHMARK(AppendStdStringConstLiteral) ->Name("std::string str; ... str += \"abbaabbaabbaabba\";"); +BENCHMARK(AppendLstringConstLiteral<8>) ->Name("lstringa<8> str; ... str += \"abbaabbaabbaabba\";"); +BENCHMARK(AppendLstringConstLiteral<128>) ->Name("lstringa<128> str; ... str += \"abbaabbaabbaabba\";"); +BENCHMARK(AppendLstringConstLiteral<512>) ->Name("lstringa<512> str; ... str += \"abbaabbaabbaabba\";"); +BENCHMARK(AppendLstringConstLiteral<1024>)->Name("lstringa<1024> str; ... str += \"abbaabbaabbaabba\";"); + +void AppendStreamStrConstLiteral(benchmark::State& state) { + std::string s1 = TEXT_16; + for (auto _: state) { + std::string result; + std::stringstream s; + for (size_t c = 0; c < 32; c++) { + s << s1 << TEXT_16; + } + result = s.str(); + #ifdef CHECK_RESULT + if (result.size() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + } +} + +void AppendStdStrStrConstLiteral(benchmark::State& state) { + std::string p1 = TEXT_16; + for (auto _: state) { + std::string result; + for (size_t c = 0; c < 32; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.size() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +} + +template +void AppendLstringStrConstLiteral(benchmark::State& state) { + stringa p1 = TEXT_16; + for (auto _: state) { + lstringa result; + for (size_t c = 0; c < 32; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +} + +BENCHMARK(__)->Name("-- Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length --")->Repetitions(1); +BENCHMARK(AppendStreamStrConstLiteral) ->Name("std::stringstream str; ... str << str_var << \"abbaabbaabbaabba\";"); +BENCHMARK(AppendStdStrStrConstLiteral) ->Name("std::string str; ... str += str_var + \"abbaabbaabbaabba\";"); +BENCHMARK(AppendLstringStrConstLiteral<8>) ->Name("lstringa<8> str; ... str += str_var + \"abbaabbaabbaabba\";"); +BENCHMARK(AppendLstringStrConstLiteral<128>) ->Name("lstringa<128> str; ... str += str_var + \"abbaabbaabbaabba\";"); +BENCHMARK(AppendLstringStrConstLiteral<512>) ->Name("lstringa<512> str; ... str += str_var + \"abbaabbaabbaabba\";"); +BENCHMARK(AppendLstringStrConstLiteral<1024>) ->Name("lstringa<1024> str; ... str += str_var + \"abbaabbaabbaabba\";"); + + +void AppendStreamStrConstLiteralBig(benchmark::State& state) { + std::string s1 = TEXT_16; + for (auto _: state) { + std::string result; + std::stringstream s; + for (size_t c = 0; c < 2048; c++) { + s << s1 << TEXT_16; + } + result = s.str(); + #ifdef CHECK_RESULT + if (result.size() != 1024 * 64) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + } +} + +void AppendStdStrStrConstLiteralBig(benchmark::State& state) { + std::string p1 = TEXT_16; + for (auto _: state) { + std::string result; + for (size_t c = 0; c < 2048; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.size() != 1024 * 64) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +} + +template +void AppendLstringStrConstLiteralBig(benchmark::State& state) { + stringa p1 = TEXT_16; + for (auto _: state) { + lstringa result; + for (size_t c = 0; c < 2048; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024 * 64) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +} + +BENCHMARK(__)->Name("-- Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length --")->Repetitions(1); +BENCHMARK(AppendStreamStrConstLiteralBig) ->Name("std::stringstream str; ... str << str_var << \"abbaabbaabbaabba\"; 2048 times"); +BENCHMARK(AppendStdStrStrConstLiteralBig) ->Name("std::string str; ... str += str_var + \"abbaabbaabbaabba\"; 2048 times"); +BENCHMARK(AppendLstringStrConstLiteralBig<8>) ->Name("lstringa<8> str; ... str += str_var + \"abbaabbaabbaabba\"; 2048 times"); +BENCHMARK(AppendLstringStrConstLiteralBig<128>) ->Name("lstringa<128> str; ... str += str_var + \"abbaabbaabbaabba\"; 2048 times"); +BENCHMARK(AppendLstringStrConstLiteralBig<512>) ->Name("lstringa<512> str; ... str += str_var + \"abbaabbaabbaabba\"; 2048 times"); +BENCHMARK(AppendLstringStrConstLiteralBig<1024>) ->Name("lstringa<1024> str; ... str += str_var + \"abbaabbaabbaabba\"; 2048 times"); + +void AppendStream2String(benchmark::State& state) { + std::string s1 = TEXT_16; + std::string s2 = TEXT_16; + for (auto _: state) { + std::string result; + std::stringstream s; + for (size_t c = 0; c < 32; c++) { + s << s1 << s2; + } + result = s.str(); + #ifdef CHECK_RESULT + if (result.size() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + benchmark::DoNotOptimize(s2); + } +} + +void AppendStdStr2String(benchmark::State& state) { + std::string s1 = TEXT_16; + std::string s2 = TEXT_16; + + for (auto _: state) { + std::string result; + for (size_t c = 0; c < 32; c++) { + result += s1 + s2; + } + #ifdef CHECK_RESULT + if (result.size() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + benchmark::DoNotOptimize(s2); + } +} + +template +void AppendLstring2String(benchmark::State& state) { + stra s1 = TEXT_16; + stra s2 = TEXT_16; + for (auto _: state) { + lstringa result; + for (size_t c = 0; c < 32; c++) { + result += s1 + s2; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + benchmark::DoNotOptimize(s2); + } +} + +BENCHMARK(__)->Name("-- Append 2 string of 16 bytes 32 times, 1024 total length --")->Repetitions(1); +BENCHMARK(AppendStream2String) ->Name("std::stringstream str; ... str << str_var1 << str_var2;"); +BENCHMARK(AppendStdStr2String) ->Name("std::string str; ... str += str_var1 + str_var2;"); +BENCHMARK(AppendLstring2String<8>) ->Name("lstringa<16> str; ... str += str_var1 + str_var2;"); +BENCHMARK(AppendLstring2String<128>) ->Name("lstringa<128> str; ... str += str_var1 + str_var2;"); +BENCHMARK(AppendLstring2String<512>) ->Name("lstringa<512> str; ... str += str_var1 + str_var2;"); +BENCHMARK(AppendLstring2String<1024>) ->Name("lstringa<1024> str; ... str += str_var1 + str_var2;"); + +void AppendStreamStrNumStr(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + std::stringstream t; + t << "test = " << k << " times"; + std::string result = t.str(); + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +} + +void AppendStdStringStrNumStr(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + std::string result = "test = " + std::to_string(k) + " times"; + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +} + +void AppendSprintfStrNumStr(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + char buf[100]; + std::sprintf(buf, "test = %u times", k); + std::string result = buf; + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +} + +void AppendFormatStrNumStr(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + std::string result = std::format("test = {} times", k); + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +} + +template +void AppendSimStrStrNumStrF(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + T result; + result.format("test = {} times", k); + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +} + +template +void AppendSimStrStrNumStr(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + T result = "test = "_ss + k + " times"; + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +} + +BENCHMARK(__)->Name("-- Append text, number, text --")->Repetitions(1); +BENCHMARK(AppendStreamStrNumStr) ->Name("std::stringstream str; str << \"test = \" << k << \" times\";"); +BENCHMARK(AppendStdStringStrNumStr) ->Name("std::string str = \"test = \" + std::to_string(k) + \" times\";"); +BENCHMARK(AppendSprintfStrNumStr) ->Name("char buf[100]; sprintf(buf, \"test = %u times\", k); std::string str = buf;"); +BENCHMARK(AppendFormatStrNumStr) ->Name("std::string str = std::format(\"test = {} times\", k);"); +BENCHMARK(AppendSimStrStrNumStrF>) ->Name("lstringa<8> str; str.format(\"test = {} times\", k);"); +BENCHMARK(AppendSimStrStrNumStrF>)->Name("lstringa<32> str; str.format(\"test = {} times\", k);"); +BENCHMARK(AppendSimStrStrNumStr>) ->Name("lstringa<8> str = \"test = \" + k + \" times\";"); +BENCHMARK(AppendSimStrStrNumStr>) ->Name("lstringa<32> str = \"test = \" + k + \" times\";"); +BENCHMARK(AppendSimStrStrNumStr) ->Name("stringa str = \"test = \" + k + \" times\";"); + +const char NUMBER_LIST[] = "1-!- 2-!- 3-!- 4 -!- 5-!- 6 -!- 7-!- -8-!- 0xaF-!- 15-!- 010"; // 218 + +void SplitConvertIntStdString(benchmark::State& state) { + std::string numbers = NUMBER_LIST; + for (auto _: state) { + int total = 0; + for (size_t start = 0; start < numbers.length(); ) { + int delim = numbers.find("-!-", start); + if (delim == std::string::npos) { + delim = numbers.size(); + } + std::string part = numbers.substr(start, delim - start); + total += std::strtol(part.c_str(), nullptr, 0); + start = delim + 3; + } + #ifdef CHECK_RESULT + if (total != 218) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(total); + benchmark::DoNotOptimize(numbers); + } +} + +void SplitConvertIntSimStr(benchmark::State& state) { + stra numbers = NUMBER_LIST; + for (auto _: state) { + int total = 0; + for (auto splitter = numbers.splitter("-!-"); !splitter.is_done();) { + total += splitter.next().as_int(); + } + #ifdef CHECK_RESULT + if (total != 218) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(total); + benchmark::DoNotOptimize(numbers); + } +} +void SplitConvertIntSplitf(benchmark::State& state) { + stra numbers = NUMBER_LIST; + for (auto _: state) { + int total = 0; + numbers.splitf("-!-", [&](ssa& part){total += part.as_int();}); + #ifdef CHECK_RESULT + if (total != 218) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(total); + benchmark::DoNotOptimize(numbers); + } +} + +BENCHMARK(__)->Name("-- Split text and convert to int --")->Repetitions(1); +BENCHMARK(SplitConvertIntStdString) ->Name("std::string::find + substr + std::strtol"); +BENCHMARK(SplitConvertIntSimStr) ->Name("ssa::splitter + ssa::as_int"); +BENCHMARK(SplitConvertIntSplitf) ->Name("ssa::splitf + functor"); + +void ReplaceSymbolsStdStringNaiveWrong(benchmark::State& state) { + std::string_view source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + ; + std::vector> repl = { + {'&', "&"}, + {'-', ""}, + {'<', "<"}, + {'>', ">"}, + {'\'', "'"}, + {'\"', """} + }; + + auto repl_all = [](std::string& str, char s, std::string_view repl) { + size_t start_pos = 0; + while((start_pos = str.find(s, start_pos)) != std::string::npos) { + str.replace(start_pos, 1, repl); + start_pos += repl.length(); + } + }; + for (auto _: state) { + std::string result{source}; + for (const auto& r : repl) { + repl_all(result, r.first, r.second); + } +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +} + +void ReplaceSymbolsStdStringNaiveRight(benchmark::State& state) { + std::string_view source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + ; + std::vector> repl = { + {'-', ""}, + {'<', "<"}, + {'>', ">"}, + {'\'', "'"}, + {'\"', """}, + {'&', "&"}, + }; + + for (auto _: state) { + std::string result{source}; + std::string pattern; + for (const auto& r : repl) { + pattern += r.first; + } + size_t start_pos = 0; + while((start_pos = result.find_first_of(pattern, start_pos)) != std::string::npos) { + size_t idx = pattern.find(result[start_pos]); + result.replace(start_pos, 1, repl[idx].second); + start_pos += repl[idx].second.length(); + } +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +} + +void ReplaceSymbolsStdString(benchmark::State& state) { + std::string_view source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + ; + + const std::string_view repl_from = "-<>'\"&"; + const std::string_view repl_to[] = {"", "<", ">", "'", """, "&"}; + + for (auto _: state) { + std::string result; + + for (size_t start = 0; start < source.size();) { + size_t idx = source.find_first_of(repl_from, start); + if (idx == std::string::npos) { + result += source.substr(start); + break; + } + if (idx > start) { + result += source.substr(start, idx - start); + } + size_t what = repl_from.find(source[idx]); + result += repl_to[what]; + + start = idx + 1; + } +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl_from); + benchmark::DoNotOptimize(repl_to); + } +} + +template +void ReplaceSymbolsDynPatternSimStr(benchmark::State& state) { + stra source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + ; + + std::vector> repl = { + {'-', ""}, + {'<', "<"}, + {'>', ">"}, + {'\'', "'"}, + {'\"', """}, + {'&', "&"}, + }; + + for (auto _: state) { + stringa result = expr_replace_symbols{source, repl}; + +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +} + +template +void ReplaceSymbolsCons2PatternSimStr(benchmark::State& state) { + stra source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + ; + + for (auto _: state) { + stringa result = e_repl_const_symbols(source, + '-', "", + '<', "<", + '>', ">", + '\'', "'", + '\"', """, + '&', "&" + ); + +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +} + +BENCHMARK(__)->Name("-- Replace symbols in text ~400 symbols --")->Repetitions(1); +BENCHMARK(ReplaceSymbolsStdStringNaiveWrong) ->Name("Naive (and wrong) replace symbols with std::string find + replace"); +BENCHMARK(ReplaceSymbolsStdStringNaiveRight) ->Name("replace symbols with std::string find_first_of + replace"); +BENCHMARK(ReplaceSymbolsStdString) ->Name("replace symbols with std::string_view find_first_of + copy"); +BENCHMARK(ReplaceSymbolsDynPatternSimStr) ->Name("replace runtime symbols with string expressions and without remembering all search results"); +BENCHMARK(ReplaceSymbolsDynPatternSimStr) ->Name("replace runtime symbols with simstr and memorization of all search results"); +BENCHMARK(ReplaceSymbolsCons2PatternSimStr) ->Name("replace const symbols with string expressions and without remembering all search results"); +BENCHMARK(ReplaceSymbolsCons2PatternSimStr) ->Name("replace const symbols with string expressions and memorization of all search results"); + + +void ShortReplaceSymbolsStdStringNaiveWrong(benchmark::State& state) { + std::string_view source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ; + std::vector> repl = { + {'&', "&"}, + {'-', ""}, + {'<', "<"}, + {'>', ">"}, + {'\'', "'"}, + {'\"', """} + }; + + auto repl_all = [](std::string& str, char s, std::string_view repl) { + size_t start_pos = 0; + while((start_pos = str.find(s, start_pos)) != std::string::npos) { + str.replace(start_pos, 1, repl); + start_pos += repl.length(); + } + }; + for (auto _: state) { + std::string result{source}; + for (const auto& r : repl) { + repl_all(result, r.first, r.second); + } +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +} + +void ShortReplaceSymbolsStdStringNaiveRight(benchmark::State& state) { + std::string_view source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ; + std::vector> repl = { + {'-', ""}, + {'<', "<"}, + {'>', ">"}, + {'\'', "'"}, + {'\"', """}, + {'&', "&"}, + }; + + for (auto _: state) { + std::string result{source}; + std::string pattern; + for (const auto& r : repl) { + pattern += r.first; + } + size_t start_pos = 0; + while((start_pos = result.find_first_of(pattern, start_pos)) != std::string::npos) { + size_t idx = pattern.find(result[start_pos]); + result.replace(start_pos, 1, repl[idx].second); + start_pos += repl[idx].second.length(); + } +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +} + +void ShortReplaceSymbolsStdString(benchmark::State& state) { + std::string_view source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ; + + const std::string_view repl_from = "-<>'\"&"; + const std::string_view repl_to[] = {"", "<", ">", "'", """, "&"}; + + for (auto _: state) { + std::string result; + + for (size_t start = 0; start < source.size();) { + size_t idx = source.find_first_of(repl_from, start); + if (idx == std::string::npos) { + result += source.substr(start); + break; + } + if (idx > start) { + result += source.substr(start, idx - start); + } + size_t what = repl_from.find_first_of(source[idx]); + result += repl_to[what]; + + start = idx + 1; + } +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl_from); + benchmark::DoNotOptimize(repl_to); + } +} + +template +void ShortReplaceSymbolsDynPatternSimStr(benchmark::State& state) { + stra source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ; + + std::vector> repl = { + {'-', ""}, + {'<', "<"}, + {'>', ">"}, + {'\'', "'"}, + {'\"', """}, + {'&', "&"}, + }; + + for (auto _: state) { + stringa result = expr_replace_symbols{source, repl}; + +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +} + +template +void ShortReplaceSymbolsCons2PatternSimStr(benchmark::State& state) { + stra source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ; + + for (auto _: state) { + stringa result = e_repl_const_symbols(source, + '-', "", + '<', "<", + '>', ">", + '\'', "'", + '\"', """, + '&', "&" + ); + +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +} + +BENCHMARK(__)->Name("-- Replace symbols in text ~40 symbols --")->Repetitions(1); +BENCHMARK(ShortReplaceSymbolsStdStringNaiveWrong) ->Name("Short Naive (and wrong) replace symbols with std::string find + replace"); +BENCHMARK(ShortReplaceSymbolsStdStringNaiveRight) ->Name("Short replace symbols with std::string find_first_of + replace"); +BENCHMARK(ShortReplaceSymbolsStdString) ->Name("Short replace symbols with std::string_view find_first_of + copy"); +BENCHMARK(ShortReplaceSymbolsDynPatternSimStr) ->Name("Short replace runtime symbols with string expressions and without remembering all search results"); +BENCHMARK(ShortReplaceSymbolsDynPatternSimStr) ->Name("Short replace runtime symbols with simstr and memorization of all search results"); +BENCHMARK(ShortReplaceSymbolsCons2PatternSimStr) ->Name("Short replace const symbols with string expressions and without remembering all search results"); +BENCHMARK(ShortReplaceSymbolsCons2PatternSimStr) ->Name("Short replace const symbols with string expressions and memorization of all search results"); + +template +void ReplaceAllLongerStdString(benchmark::State& state) { + std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + std::string_view sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + std::string_view pattern = "bb"; + std::string_view repl = "----"; + + std::string big_source, big_sample; + for (int i = 0; i < Long; i++) { + big_source += source; + big_sample += sample; + } + + for (auto _: state) { + std::string result{big_source}; + size_t start_pos = 0; + while((start_pos = result.find(pattern, start_pos)) != std::string::npos) { + result.replace(start_pos, pattern.length(), repl); + start_pos += repl.length(); + } +#ifdef CHECK_RESULT + if (result != big_sample) { + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +} + +template +void ReplaceAllLongerSimString(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + lstringa result = big_source; + result.replace("bb", "----"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +} + +template +void ReplaceAllLongerSimStringExpr(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + stringa result = e_repl(big_source.to_str(), "bb", "----"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +} + +template +void ReplaceAllEqualStdString(benchmark::State& state) { + std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + std::string_view sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + std::string_view pattern = "bb"; + std::string_view repl = "--"; + + std::string big_source, big_sample; + for (int i = 0; i < Long; i++) { + big_source += source; + big_sample += sample; + } + + for (auto _: state) { + std::string result{big_source}; + size_t start_pos = 0; + while((start_pos = result.find(pattern, start_pos)) != std::string::npos) { + result.replace(start_pos, pattern.length(), repl); + start_pos += repl.length(); + } +#ifdef CHECK_RESULT + if (result != big_sample) { + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +} + +template +void ReplaceAllEqualSimString(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + lstringa<2048> big_source{Long, source}, big_sample{Long, sample}; + + for (auto _: state) { + lstringa result = big_source; + result.replace("bb", "--"); + + #ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +} + +template +void ReplaceAllEqualSimStringExpr(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + ssa pattern = "bb"; + ssa repl = "--"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + stringa result = e_repl(big_source.to_str(), "bb", "--"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +} + +BENCHMARK(__)->Name("----- Replace All Str To Longer Size ---------")->Repetitions(1); +BENCHMARK(ReplaceAllLongerStdString<1>) ->Name("replace bb to ---- in std::string|64"); +BENCHMARK(ReplaceAllLongerStdString<4>) ->Name("replace bb to ---- in std::string|256"); +BENCHMARK(ReplaceAllLongerStdString<8>) ->Name("replace bb to ---- in std::string|512"); +BENCHMARK(ReplaceAllLongerStdString<16>) ->Name("replace bb to ---- in std::string|1024"); +BENCHMARK(ReplaceAllLongerStdString<32>) ->Name("replace bb to ---- in std::string|2048"); +BENCHMARK(ReplaceAllLongerSimString<8, 1>) ->Name("replace bb to ---- in lstringa<8>|64"); +BENCHMARK(ReplaceAllLongerSimString<8, 4>) ->Name("replace bb to ---- in lstringa<8>|256"); +BENCHMARK(ReplaceAllLongerSimString<8, 8>) ->Name("replace bb to ---- in lstringa<8>|512"); +BENCHMARK(ReplaceAllLongerSimString<8, 16>) ->Name("replace bb to ---- in lstringa<8>|1024"); +BENCHMARK(ReplaceAllLongerSimString<8, 32>) ->Name("replace bb to ---- in lstringa<8>|2048"); +BENCHMARK(ReplaceAllLongerSimStringExpr<1>) ->Name("replace bb to ---- by init stringa|64"); +BENCHMARK(ReplaceAllLongerSimStringExpr<4>) ->Name("replace bb to ---- by init stringa|256"); +BENCHMARK(ReplaceAllLongerSimStringExpr<8>) ->Name("replace bb to ---- by init stringa|512"); +BENCHMARK(ReplaceAllLongerSimStringExpr<16>) ->Name("replace bb to ---- by init stringa|1024"); +BENCHMARK(ReplaceAllLongerSimStringExpr<32>) ->Name("replace bb to ---- by init stringa|2048"); + +BENCHMARK(__)->Name("----- Replace All Str To Same Size ---------")->Repetitions(1); +BENCHMARK(ReplaceAllEqualStdString<1>) ->Name("replace bb to -- in std::string|64"); +BENCHMARK(ReplaceAllEqualStdString<4>) ->Name("replace bb to -- in std::string|256"); +BENCHMARK(ReplaceAllEqualStdString<8>) ->Name("replace bb to -- in std::string|512"); +BENCHMARK(ReplaceAllEqualStdString<16>) ->Name("replace bb to -- in std::string|1024"); +BENCHMARK(ReplaceAllEqualStdString<32>) ->Name("replace bb to -- in std::string|2048"); +BENCHMARK(ReplaceAllEqualSimString<8, 1>) ->Name("replace bb to -- in lstringa<8>|64"); +BENCHMARK(ReplaceAllEqualSimString<8, 4>) ->Name("replace bb to -- in lstringa<8>|256"); +BENCHMARK(ReplaceAllEqualSimString<8, 8>) ->Name("replace bb to -- in lstringa<8>|512"); +BENCHMARK(ReplaceAllEqualSimString<8, 16>) ->Name("replace bb to -- in lstringa<8>|1024"); +BENCHMARK(ReplaceAllEqualSimString<8, 32>) ->Name("replace bb to -- in lstringa<8>|2048"); +BENCHMARK(ReplaceAllEqualSimStringExpr<1>) ->Name("replace bb to -- by init stringa|64"); +BENCHMARK(ReplaceAllEqualSimStringExpr<4>) ->Name("replace bb to -- by init stringa|256"); +BENCHMARK(ReplaceAllEqualSimStringExpr<8>) ->Name("replace bb to -- by init stringa|512"); +BENCHMARK(ReplaceAllEqualSimStringExpr<16>) ->Name("replace bb to -- by init stringa|1024"); +BENCHMARK(ReplaceAllEqualSimStringExpr<32>) ->Name("replace bb to -- by init stringa|2048"); + +std::vector prepareTestStrings(size_t length, size_t delta, size_t count) { + std::vector result; + result.reserve(count); + + struct expr_rand { + using symb_type = u8s; + size_t len; + size_t length() const noexcept { + return len; + } + char* place(char* ptr) const { + for (size_t idx = len; idx > 0; idx--) { + *ptr++ = char(' ' + std::rand() % 200); + } + return ptr; + } + }; + + for (size_t idx = 0; idx < count; idx++) { + result.emplace_back(expr_rand{length + std::rand() % delta}); + } + return result; +} + +std::vector bs_sim = prepareTestStrings(30, 20, 10'000); + +std::vector prepareTestStdStrings() { + std::vector result; + result.reserve(bs_sim.size()); + for (const auto& s: bs_sim) { + result.emplace_back(s.to_string()); + } + return result; +} + +std::vector bs_std = prepareTestStdStrings(); + +void HashMapSimStr(benchmark::State& state) { + for (auto _: state) { + hashStrMapA store; + for (size_t idx = 0; idx < bs_sim.size(); idx++) { + store.try_emplace(bs_sim[idx], idx); + } +#ifdef CHECK_RESULT + if (store.size() != bs_sim.size()) { + state.SkipWithError("bad inserts"); + } +#endif + for (size_t idx = 0; idx < bs_sim.size(); idx++) { + auto find = store.find(bs_sim[idx]); + size_t res = find->second; +#ifdef CHECK_RESULT + if (res != idx) { + state.SkipWithError("bad find"); + } +#endif + benchmark::DoNotOptimize(res); + } + } +} + +void HashMapStdStr(benchmark::State& state) { + for (auto _: state) { + std::unordered_map store; + for (size_t idx = 0; idx < bs_std.size(); idx++) { + store.try_emplace(bs_std[idx], idx); + } +#ifdef CHECK_RESULT + if (store.size() != bs_std.size()) { + state.SkipWithError("bad inserts"); + } +#endif + for (size_t idx = 0; idx < bs_std.size(); idx++) { + auto find = store.find(bs_std[idx]); + size_t res = find->second; +#ifdef CHECK_RESULT + if (res != idx) { + state.SkipWithError("bad find"); + } +#endif + benchmark::DoNotOptimize(res); + } + } +} + +void HashMapSimSsa(benchmark::State& state) { + for (auto _: state) { + hashStrMapA store; + for (size_t idx = 0; idx < bs_sim.size(); idx++) { + store.emplace(bs_sim[idx], idx); + } +#ifdef CHECK_RESULT + if (store.size() != bs_sim.size()) { + state.SkipWithError("bad inserts"); + } +#endif + for (size_t idx = 0; idx < bs_sim.size(); idx++) { + ssa key = bs_sim[idx]; + auto find = store.find(key); + size_t res = find->second; +#ifdef CHECK_RESULT + if (res != idx) { + state.SkipWithError("bad find"); + } +#endif + benchmark::DoNotOptimize(res); + } + } +} + +void HashMapStdStrView(benchmark::State& state) { + for (auto _: state) { + std::unordered_map store; + for (size_t idx = 0; idx < bs_std.size(); idx++) { + store.emplace(bs_std[idx], idx); + } +#ifdef CHECK_RESULT + if (store.size() != bs_std.size()) { + state.SkipWithError("bad inserts"); + } +#endif + for (size_t idx = 0; idx < bs_std.size(); idx++) { + std::string_view key = bs_std[idx]; + auto find = store.find(std::string{key}); + size_t res = find->second; +#ifdef CHECK_RESULT + if (res != idx) { + state.SkipWithError("bad find"); + } +#endif + benchmark::DoNotOptimize(res); + } + } +} + +BENCHMARK(__)->Name("----- Hash Map insert and find ---------")->Repetitions(1); +BENCHMARK(HashMapSimStr)->Name("hashStrMapA emplace & find stringa;"); +BENCHMARK(HashMapStdStr)->Name("std::unordered_map emplace & find std::string;"); +BENCHMARK(HashMapSimSsa)->Name("hashStrMapA emplace & find ssa;"); +BENCHMARK(HashMapStdStrView)->Name("std::unordered_map emplace & find std::string_view;"); + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Набор тестов, имитирующий довольно типовой сценарий, похож на то, что встречалось в работе +// По имеющимся данным о неких функциях и их параметрах - построить полное имя функции +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +enum class Types { + int2, + int4, + int8, + bytea, + text, + char_, + varchar, + boolean, + last, +}; + +const ssa type_names[] = { + "int2", + "int4", + "int8", + "bytea", + "text", + "char", + "varchar", + "boolean" +}; + +const std::string_view type_names_sv[] = { + "int2", + "int4", + "int8", + "bytea", + "text", + "char", + "varchar", + "boolean" +}; + +constexpr bool is_power_of_two_or_zero(uint32_t value) { + return !(value & (value - 1)); +} + +struct type_set { + uint32_t value; + void to_simstr(mutable_str auto& str) const { + if (!value) { + str += "{?}"; + } else if (value == 0xFFFFFFFF) { + str += "any"; + } else { + if (!is_power_of_two_or_zero(value)) { + str += "{"; + } + bool add_comma = false; + for (unsigned idx = 0; idx < (unsigned)Types::last; idx++) { + if (value & (1 << idx)) { + str += e_if(add_comma, ", ") + type_names[idx]; + add_comma = true; + } + } + if (!is_power_of_two_or_zero(value)) { + str += "}"; + } + } + } + auto get_simstr() const { + lstringa<128> str; + if (!value) { + str = "{?}"; + } else if (value == 0xFFFFFFFF) { + str = "any"; + } else { + if (!is_power_of_two_or_zero(value)) { + str = "{"; + } + bool add_comma = false; + for (unsigned idx = 0; idx < (unsigned)Types::last; idx++) { + if (value & (1 << idx)) { + str += e_if(add_comma, ", ") + type_names[idx]; + add_comma = true; + } + } + if (!is_power_of_two_or_zero(value)) { + str += "}"; + } + } + return str; + } + void to_stdstr(std::string& str) const { + if (!value) { + str += "{?}"; + } else if (value == 0xFFFFFFFF) { + str += "any"; + } else { + if (!is_power_of_two_or_zero(value)) { + str += "{"; + } + bool add_comma = false; + for (unsigned idx = 0; idx < (unsigned)Types::last; idx++) { + if (value & (1 << idx)) { + if (add_comma) { + str += ", "; + } + str += type_names_sv[idx]; + add_comma = true; + } + } + if (!is_power_of_two_or_zero(value)) { + str += "}"; + } + } + } + void to_stream(std::ostream& str) const { + if (!value) { + str << "{?}"; + } else if (value == 0xFFFFFFFF) { + str << "any"; + } else { + if (!is_power_of_two_or_zero(value)) { + str << "{"; + } + bool add_comma = false; + for (unsigned idx = 0; idx < (unsigned)Types::last; idx++) { + if (value & (1 << idx)) { + if (add_comma) { + str << ", "; + } + str << type_names_sv[idx]; + add_comma = true; + } + } + if (!is_power_of_two_or_zero(value)) { + str << "}"; + } + } + } +}; + +struct param { + type_set allowed_types; + bool optional; +}; + +struct function { + stringa name; + std::string std_name; + std::vector params; + Types ret_type; + bool has_ret_type_resolver; + bool unlim_params; + // Построение полного имени с помощью simstr строковых объектов и выражений + stringa build_full_name() const { + lstringa<512> str = e_choice(has_ret_type_resolver, "any", type_names[(unsigned)ret_type]) + " " + name + "("; + + bool add_comma = false; + + for (const auto& param : params) { + str += e_if(add_comma, ", ") + e_if(param.optional, "["); + param.allowed_types.to_simstr(str); + if (param.optional) { + str += "]"; + } + add_comma = true; + } + return str + e_if(unlim_params, e_if(add_comma, ", ") + "...") + ")"; + } + stringa build_full_name1() const { + lstringa<512> str = e_choice(has_ret_type_resolver, "any", type_names[(unsigned)ret_type]) + " " + name + "("; + + bool add_comma = false; + + for (const auto& param : params) { + str += e_if(add_comma, ", ") + e_if(param.optional, "[") + param.allowed_types.get_simstr() + e_if(param.optional, "]"); + add_comma = true; + } + return str + e_if(unlim_params, e_if(add_comma, ", ") + "...") + ")"; + } + // Построение полного имени с помощью std::string + std::string build_full_name_std() const { + std::string str{has_ret_type_resolver ? "any"sv : type_names_sv[(unsigned)ret_type]}; + str += " "; + str += std_name; + str += "("; + + bool add_comma = false; + + for (const auto& param : params) { + if (add_comma) { + str += ", "; + } + if (param.optional) { + str += "["; + } + param.allowed_types.to_stdstr(str); + if (param.optional) { + str += "]"; + } + add_comma = true; + } + if (unlim_params) { + if (add_comma) { + str += ", "; + } + str += "..."; + } + str += ")"; + //std::cout << "Len=" << str.length() << ", Cap=" << str.capacity() << "\n"; + return str; + } + // Построение полного имени с помощью std::string + std::string build_full_name_std1() const { + std::string str{has_ret_type_resolver ? "any"sv : type_names_sv[(unsigned)ret_type]}; + str += " " + std_name + "("; + + bool add_comma = false; + + for (const auto& param : params) { + if (add_comma) { + str += ", "; + } + if (param.optional) { + str += "["; + } + param.allowed_types.to_stdstr(str); + if (param.optional) { + str += "]"; + } + add_comma = true; + } + if (unlim_params) { + if (add_comma) { + str += ", "; + } + str += "..."; + } + str += ")"; + //std::cout << "Len=" << str.length() << ", Cap=" << str.capacity() << "\n"; + return str; + } + // Построение полного имени с помощью std::ostringstream + std::string build_full_name_stream() const { + std::ostringstream str; + if (has_ret_type_resolver) { + str << "any"; + } else { + str << type_names_sv[(unsigned)ret_type]; + } + str << " " << std_name << "("; + + bool add_comma = false; + + for (const auto& param : params) { + if (add_comma) { + str << ", "; + } + if (param.optional) { + str << "["; + } + param.allowed_types.to_stream(str); + if (param.optional) { + str << "]"; + } + add_comma = true; + } + if (unlim_params) { + if (add_comma) { + str << ", "; + } + str << "..."; + } + str << ")"; + return str.str(); + } +}; +// Тестовые варианты функций +const struct { + function f; + std::string_view check; +} functions[] = { + {{"func1", "func1", {}, Types::boolean, true, true}, "any func1(...)"}, + {{"function2", "function2", {{4, false}, {12, true}}, Types::int2, false, false}, "int2 function2(int8, [{int8, bytea}])"}, + {{"func3", "func3", {{16, false}, {7, false}, {32, true}}, Types::char_, false, true}, "char func3(text, {int2, int4, int8}, [char], ...)"}, + {{"function4", "function4", {{10, false}, {64, false}, {31, true}}, Types::char_, true, false}, "any function4({int4, bytea}, varchar, [{int2, int4, int8, bytea, text}])"}, + {{"f5", "f5", {{10, false}, {64, false}, {0xFFFFFFFF, false}}, Types::text, false, true}, "text f5({int4, bytea}, varchar, any, ...)"}, +}; + +// Замеры скорости выполнения разных вариантов + +//> stringa build_full_name() const { +void BuildFuncNameSimStr(benchmark::State& state) { + for (auto _: state) { + for (const auto& f : functions) { + stringa res = f.f.build_full_name(); + benchmark::DoNotOptimize(res); + #ifdef CHECK_RESULT + if (res != stra{f.check}) { + std::cout << res << "\n"; + state.SkipWithError("not equal"); + break; + } + #endif + } + } +} + +//> stringa build_full_name1() const { +void BuildFuncNameSimStr1(benchmark::State& state) { + for (auto _: state) { + for (const auto& f : functions) { + stringa res = f.f.build_full_name1(); + benchmark::DoNotOptimize(res); + #ifdef CHECK_RESULT + if (res != stra{f.check}) { + std::cout << res << "\n"; + state.SkipWithError("not equal"); + break; + } + #endif + } + } +} + +//> std::string build_full_name_std() const { +void BuildFuncNameStdStr(benchmark::State& state) { + for (auto _: state) { + for (const auto& f : functions) { + std::string res = f.f.build_full_name_std(); + benchmark::DoNotOptimize(res); + #ifdef CHECK_RESULT + if (res != f.check) { + std::cout << res << "\n"; + state.SkipWithError("not equal"); + break; + } + #endif + } + } +} + +//> std::string build_full_name_std1() const { +void BuildFuncNameStdStr1(benchmark::State& state) { + for (auto _: state) { + for (const auto& f : functions) { + std::string res = f.f.build_full_name_std1(); + benchmark::DoNotOptimize(res); + #ifdef CHECK_RESULT + if (res != f.check) { + std::cout << res << "\n"; + state.SkipWithError("not equal"); + break; + } + #endif + } + } +} + +//> std::string build_full_name_stream() const { +void BuildFuncNameStream(benchmark::State& state) { + for (auto _: state) { + for (const auto& f : functions) { + std::string res = f.f.build_full_name_stream(); + benchmark::DoNotOptimize(res); + #ifdef CHECK_RESULT + if (res != f.check) { + std::cout << res << "\n"; + state.SkipWithError("not equal"); + break; + } + #endif + } + } +} + +BENCHMARK(__)->Name("----- Build Full Func Name ---------")->Repetitions(1); +BENCHMARK(BuildFuncNameStdStr) ->Name("Build func full name std::string;"); +BENCHMARK(BuildFuncNameStdStr1) ->Name("Build func full name std::string 1;"); +BENCHMARK(BuildFuncNameStream) ->Name("Build func full name std::stream;"); +BENCHMARK(BuildFuncNameSimStr) ->Name("Build func full name stringa;"); +BENCHMARK(BuildFuncNameSimStr1) ->Name("Build func full name stringa 1;"); diff --git a/bench/comments.txt b/bench/comments.txt new file mode 100644 index 0000000..129b912 --- /dev/null +++ b/bench/comments.txt @@ -0,0 +1,351 @@ +- std::string e; +Пустые строки, ничего необычного. + +- std::string_view e; +- ssa e; +- stringa e; +- lstringa<20> e; +- lstringa<40> e; + +- std::string e = "Test text"; +Короткий литерал помещается во внутренний буфер std::string, +время тратится только на копирование 10 байтов. + +- std::string_view e = "Test text"; +И string_view, и ssa - по сути одно и то же: +указатель на текст и его длина. + +- ssa e = "Test text"; +- stringa e = "Test text"; +stringa при инициализации константным литералом так же +сохраняет только указатель на текст и его длину. + +- lstringa<20> e = "Test text"; +Внутреннего буфера хватает для размещения символов, +время уходит только на копирование байтов. + +- lstringa<40> e = "Test text"; +- std::string e = "123456789012345678901234567890"; +Вот тут уже литерал не помещается во внутренний буфер, +возникает аллокация и копирование 30-и байтов. +Но как же отстает аллокация под Windows от Linux'а, 20 vs 70 ns... + + +- std::string_view e = "123456789012345678901234567890"; +string_view и ssa по прежнему ничего не делают, кроме +запоминания указателя на текст и его размера. + +- ssa e = "123456789012345678901234567890"; +- stringa e = "123456789012345678901234567890"; +stringa на константных литералах не отстает! + +- lstringa<20> e = "123456789012345678901234567890"; +lstringa<20> может вместить в себя до 23 символов, +Очевидно, что для 30-и символов уже нужна аллокация. + +- lstringa<40> e = "123456789012345678901234567890"; +А в lstringa<40> влезает до 47 символов, так что просто +копируется 30 байтов. + +- std::string e = "Test text"; auto c{e}; +Строка в пределах SSO, так что просто копирует байты. + +- std::string_view e = "Test text"; auto c{e}; +- ssa e = "Test text"; auto c{e}; +ssa и string_view не владеют строкой, копируется +только информация о строке. + +- stringa e = "Test text"; auto c{e}; +Копирование stringa происходит быстро, +особенно если она инициализирована литералом. + +- lstringa<20> e = "Test text"; auto c{e}; +В обоих случаях хватает внутреннего буфера. + +- lstringa<40> e = "Test text"; auto c{e}; +Только копируются байты. + +- std::string e = "123456789012345678901234567890"; auto c{e}; +Копирования длинной строки вызывает аллокацию, +SSO уже не хватает. И снова как же отстаёт аллокация под Windows... + +- std::string_view e = "123456789012345678901234567890"; auto c{e}; +- ssa e = "123456789012345678901234567890"; auto c{e}; +- stringa e = "123456789012345678901234567890"; auto c{e}; +А вот у stringa копирование литерала не зависит от его длины, +сравни с предыдущим бенчмарком. + +- lstringa<20> e = "123456789012345678901234567890"; auto c{e}; +Не влезает, аллокация. + +- lstringa<40> e = "123456789012345678901234567890"; auto c{e}; +Уложили во внутренний буфер. + +- std::string::find; +Здесь "победила дружба", у всех типов по колонке примерно одинаково. +Однако, Windows и Linux явно в разных весовых категориях. + +- std::string_view::find; +- ssa::find; +- stringa::find; +- lstringa<20>::find; +- lstringa<40>::find; +- std::string copy{str_with_len_N};/15 +- std::string copy{str_with_len_N};/16 +Явно виден скачок, где заканчивается SSO и начинается аллокация. +Обратите внимание, что WASM - 32-битный, и там размер +SSO у std::string меньше, насколько я помню, 11 символов + 0. + +- std::string copy{str_with_len_N};/23 +Дальше просто добавляется время на копирование байтов. + +- std::string copy{str_with_len_N};/24 +- std::string copy{str_with_len_N};/32 +- std::string copy{str_with_len_N};/64 +- std::string copy{str_with_len_N};/128 +- std::string copy{str_with_len_N};/256 +- std::string copy{str_with_len_N};/512 +- std::string copy{str_with_len_N};/1024 +- std::string copy{str_with_len_N};/2048 +- std::string copy{str_with_len_N};/4096 +Чем длиннее строка, тем дольше создаётся копия. + +- stringa copy{str_with_len_N};/15 +Здесь stringa инициализируется не литералом, +а значит, должна сама хранить символы. + +- stringa copy{str_with_len_N};/16 +Под WASM SSO у stringa составляет 15 символов. Кроме того, +собиралось без поддержки потоков, поэтому возможно атомарный +инкремент заменён на обычный, судя по времени. + +- stringa copy{str_with_len_N};/23 +SSO в stringa до 23 символов, и даже 23 +копируются быстрее, чем 15 в std::string. + +- stringa copy{str_with_len_N};/24 +Всё, не влезаем в SSO, а значит, используем shared буфер. +Добавляется время на атомарный инкремент счётчика. + +- stringa copy{str_with_len_N};/32 +- stringa copy{str_with_len_N};/64 +- stringa copy{str_with_len_N};/128 +- stringa copy{str_with_len_N};/256 +- stringa copy{str_with_len_N};/512 +- stringa copy{str_with_len_N};/1024 +- stringa copy{str_with_len_N};/2048 +- stringa copy{str_with_len_N};/4096 +И как видно, кроме инкремента нет накладных расходов, +время копирования не зависит от длины строки. + +- lstringa<16> copy{str_with_len_N};/15 +lstringa<16> использует SSO до 23 символов. +А в WASM 32-битная архитектура, SSO до 19 символов. + +- lstringa<16> copy{str_with_len_N};/16 +- lstringa<16> copy{str_with_len_N};/23 +- lstringa<16> copy{str_with_len_N};/24 +И после начинает вести себя при копировании, как std::string. + +- lstringa<16> copy{str_with_len_N};/32 +- lstringa<16> copy{str_with_len_N};/64 +- lstringa<16> copy{str_with_len_N};/128 +- lstringa<16> copy{str_with_len_N};/256 +- lstringa<16> copy{str_with_len_N};/512 +- lstringa<16> copy{str_with_len_N};/1024 +- lstringa<16> copy{str_with_len_N};/2048 +- lstringa<16> copy{str_with_len_N};/4096 +- lstringa<512> copy{str_with_len_N};/8 +А вот lstringa<512> имеет гораздо больший внутренний +буфер и копирует символы без аллокации. + +- lstringa<512> copy{str_with_len_N};/16 +- lstringa<512> copy{str_with_len_N};/32 +- lstringa<512> copy{str_with_len_N};/64 +- lstringa<512> copy{str_with_len_N};/128 +- lstringa<512> copy{str_with_len_N};/256 +- lstringa<512> copy{str_with_len_N};/512 +Даже 512 символов копируются быстрее, чем +одна аллокация или атомарный инкремент. + +- lstringa<512> copy{str_with_len_N};/1024 +А дальше уже как у всех + +- lstringa<512> copy{str_with_len_N};/2048 +- lstringa<512> copy{str_with_len_N};/4096 + +- std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10); +В simstr для конвертации в число достаточно куска строки, +нет нужды в null терминированности. Ближайший аналог такого +поведения "std::from_chars", но он к сожалению очень ограничен +по возможностям. Здесь я попытался произвести тесты, близкие по +логике к работе std::from_chars + +- std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10); +from_chars требует точного указания основания счисления, +не допускает знаков плюс, пробелов, префиксов 0x и т.п. + +- stringa s = "123456789"; int res = s.to_int +Здесь для to_int заданы такие же ограничения - проверять переполнение, +десятичная система, без лидирующих пробелов и знака плюс + +- ssa s = "123456789"; int res = s.to_int +- lstringa<20> s = "123456789"; int res = s.to_int +- std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16); +Всё то же, только для 16ричной системы + +- std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16); +- stringa s = "abcDef"; int res = s.to_int +- ssa s = "abcDef"; int res = s.to_int +- lstringa<20> s = "abcDef"; int res = s.to_int +- std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0); +А здесь уже парсинг произвольного числа. + +- stringa s = " 123456789"; int res = s.to_int; // Check overflow +- ssa s = " 123456789"; int res = s.to_int; // No check overflow +- std::stringstream str; ... str << "abbaabbaabbaabba"; +- std::string str; ... str += "abbaabbaabbaabba"; +- lstringa<8> str; ... str += "abbaabbaabbaabba"; +- lstringa<128> str; ... str += "abbaabbaabbaabba"; +Чем больше внутренний буфер, тем меньше раз требуется +аллокация, тем быстрее результат. + +- lstringa<512> str; ... str += "abbaabbaabbaabba"; +- lstringa<1024> str; ... str += "abbaabbaabbaabba"; +- std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; +- std::string str; ... str += str_var + "abbaabbaabbaabba"; +- lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; +- lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; +- lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; +- lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; +- std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; +- std::string str; ... str += str_var + "abbaabbaabbaabba"; +- lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; +- lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; +- lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; +- lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; +- std::stringstream str; ... str << str_var1 << str_var2; +- std::string str; ... str += str_var1 + str_var2; +- lstringa<16> str; ... str += str_var1 + str_var2; +- lstringa<128> str; ... str += str_var1 + str_var2; +- lstringa<512> str; ... str += str_var1 + str_var2; +- lstringa<1024> str; ... str += str_var1 + str_var2; +- std::stringstream str; str << "test = " << k << " times"; +- std::string str = "test = " + std::to_string(k) + " times"; +- char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf; +- std::string str = std::format("test = {} times", k); +- lstringa<8> str; str.format("test = {} times", k); +В simstr format с первого раза не помещается в такую строку без аллокации. + +- lstringa<32> str; str.format("test = {} times", k); +А в такую помещается. Используйте сразу буфера подходящего размера. + +- lstringa<8> str = "test = " + k + " times"; +Результат не помещается в SSO, возникает аллокация. + +- lstringa<32> str = "test = " + k + " times"; +А здесь и ниже - результат укладывается в SSO. +Ещё раз - используйте сразу буфера подходящего размера. + +- stringa str = "test = " + k + " times"; +Под WASM размер SSO 15 символов, что явно не хватает для размещения +результата, отсюда и такое время. + +- std::string::find + substr + std::strtol +- ssa::splitter + ssa::as_int + +- Naive (and wrong) replace symbols with std::string find + replace +Это наивная реализация, которая неверно отработает на +таких заменах, как 'a'->'b' и 'b'->'a'. Но если замены не конфликтуют, +то работает быстро. + +- replace symbols with std::string find_first_of + replace +Дальше уже правильные реализации, не зависящие от конфликтующих замен. + +- replace symbols with std::string_view find_first_of + copy +- replace runtime symbols with string expressions and without remembering all search results +- replace runtime symbols with simstr and memorization of all search results +- replace const symbols with string expressions and without remembering all search results +- replace const symbols with string expressions and memorization of all search results +- Short Naive (and wrong) replace symbols with std::string find + replace +- Short replace symbols with std::string find_first_of + replace +- Short replace symbols with std::string_view find_first_of + copy +- Short replace runtime symbols with string expressions and without remembering all search results +- Short replace runtime symbols with simstr and memorization of all search results +- Short replace const symbols with string expressions and without remembering all search results +- Short replace const symbols with string expressions and memorization of all search results + +- replace bb to ---- in 64 std::string +Тут проверяется тяжелый случай - замена подстроки на более +длинную. Обычная реализация несколько раз передвигает хвост. + +- replace bb to ---- in 64 lstringa<8> +- replace bb to ---- in 64 str by init stringa +- replace bb to ---- in 256 std::string +- replace bb to ---- in 256 lstringa<8> +- replace bb to ---- in 256 str by init stringa +- replace bb to ---- in 512 std::string +- replace bb to ---- in 512 lstringa<8> +- replace bb to ---- in 512 str by init stringa +- replace bb to ---- in 1024 std::string +- replace bb to ---- in 1024 lstringa<8> +- replace bb to ---- in 1024 str by init stringa +- replace bb to ---- in 2048 std::string +Чем длиннее строка, тем больше замедляется std::string + +- replace bb to ---- in 2048 lstringa<8> +- replace bb to ---- in 2048 str by init stringa +- replace bb to -- in 64 std::string +Идеальный случай замены - на подстроку такой же длины + +- replace bb to -- in 64 lstringa<8> +- replace bb to -- in 64 by init stringa +- replace bb to -- in 256 std::string +- replace bb to -- in 256 lstringa<8> +- replace bb to -- in 256 by init stringa +- replace bb to -- in 512 std::string +- replace bb to -- in 512 lstringa<8> +- replace bb to -- in 512 by init stringa +- replace bb to -- in 1024 std::string +- replace bb to -- in 1024 lstringa<8> +- replace bb to -- in 1024 by init stringa +- replace bb to -- in 2048 std::string +- replace bb to -- in 2048 lstringa<8> +- replace bb to -- in 2048 by init stringa +- hashStrMapA emplace & find stringa; +Вставляем в hashStrMapA 10000 stringa длиной от 30 до 50 +символов, а потом ищем их в ней + +- std::unordered_map emplace & find std::string; +То же самое c std::string и std::unordered_map + +- hashStrMapA emplace & find ssa; +Теперь вставляем stringa, а ищем ssa + +- std::unordered_map emplace & find std::string_view; +Вставляем std::string, а ищем std::string_view + +- Build func full name std::string; +Обыденная задача, подобные часто могут встретится в работе: +По неким данным сгенерировать текст. В этом случае по данным +о неких функциях сформировать их полное имя с типами параметров и +возвращаемого значения. Алгоритм на std::string. + +- Build func full name std::string 1; +Почти тот же алгоритм, но несколько последовательных ++= к строке заменены на одно += + + +. + +- Build func full name std::stream; +Строим имя функции через std::ostringstream и << + +- Build func full name stringa; +Реализация на simstr строках и строковых выражениях. +Инфа о параметрах добавляется в текущую строку + +- Build func full name stringa 1; +Реализация на simstr строках и строковых выражениях. +Инфа о параметрах добавляется во временную строку, а потом +разом добавляется в текущую строку. Позволяет операции в цикле +записать в одну строку, но чуть проигрывает по времени выполнения. + +- Пусто diff --git a/bench/header.txt b/bench/header.txt new file mode 100644 index 0000000..11e13f5 --- /dev/null +++ b/bench/header.txt @@ -0,0 +1,270 @@ + + + + + SimStr benchmarks results + + + + +

SimStr benchmarks results

+All times in ns. +Source for benchmarks diff --git a/bench/process_result.cpp b/bench/process_result.cpp new file mode 100644 index 0000000..8e57c51 --- /dev/null +++ b/bench/process_result.cpp @@ -0,0 +1,356 @@ +#include +#include +#include +#include +#include + +using namespace simstr; + +struct result_info; + +using out_t = lstringa<0>; +using results_vector = std::vector; + +bool extract_cpu_info(ssa text, ssa& res) { + // Найдём, где начинается "Run on ", потом где за ним начинается "\n---" + size_t start = text.find("Run on "), end = text.find("\n---", start); + // Если что-то не нашлось - ошибка + if (start == str::npos || end == str::npos) { + return false; + } + res = text.from_to(start, end); + return true; +} + +struct result_info { + stringa text_; + stringa platform_; + ssa current_text_{text_}; + ssa cpu_info_; + + result_info(stringa text, stringa platform) : text_(std::move(text)), platform_(std::move(platform)) { + if (!extract_cpu_info(current_text_, cpu_info_)) { + std::cerr << "Not found cpu info for platform " << platform_; + throw std::runtime_error{"Not found cpu info"}; + } + // Текущее положение поставим сразу за cpuinfo и откинем завершающие переводы строк + current_text_ = current_text_(cpu_info_.end() - current_text_.begin() + 1).trimmed_right("\n"); + } +}; + +template +T path_to_str(const std::filesystem::path& path) { + auto utf = path.u8string(); + return T{ssa{(const u8s*)utf.c_str(), utf.size()}}; +} + +std::filesystem::path str_to_path(ssa path) { + return path.to_sv(); +} + +stringa get_file_content(stra filePath) { + std::ifstream file(str_to_path(filePath), std::ios::binary | std::ios::ate); + if (!file.is_open()) { + std::cerr << "Can not open file " << filePath << std::endl; + throw std::runtime_error{"Can not open file"}; + } + std::streamsize size = file.tellg(); + file.seekg(0, std::ios::beg); + // Такой тип удобен для передачи потом в stringa + lstringsa<0> result; + file.read(result.set_size(size), size); + result.replace("\r\n", "\n"); + return result; +} + +results_vector get_results_infos() { + // Отберём в директории results все файлы с названиями, заканчивающимися на ".txt" и отсортируем их по имени + const ssa suffix = ".txt", dirForResults = "results/"; + std::vector fileNames; + for (const auto& f: std::filesystem::directory_iterator{str_to_path(dirForResults)}) { + if (f.is_regular_file()) { + auto fileName = path_to_str>(f.path().filename()); + #ifdef _WIN32 + if (fileName.ends_with_ia(suffix)) { + #else + if (fileName.ends_with(suffix)) { + #endif + fileNames.emplace_back(fileName); + } + } + } + + results_vector results; + + if (fileNames.size()) { + std::sort(fileNames.begin(), fileNames.end()); + results.reserve(fileNames.size()); + for (const auto& f : fileNames) { + ssa fileName = f; + // В начале имени файла может идти число и дефис, для сортировки, уберём их + if (auto delimeter = fileName.find('-'); delimeter != str::npos && delimeter > 0) { + if (std::get<1>(fileName(0, delimeter).to_int()) == IntConvertResult::Success) { + fileName.remove_prefix(delimeter + 1); + } + } + results.emplace_back(get_file_content(lstringa<128>{dirForResults + f}), fileName(0, -suffix.length())); + } + } + return results; +} + +void write_header(out_t& out) { + out += get_file_content("header.txt"); + +} + +void write_platforms_cpu(out_t& out, const results_vector& results) { + lstringa<1024> script = "\n"; +} + +auto repl_html_symbols(ssa text) { + return e_repl_const_symbols(text, '\"', """, '<', "<", '\'', "'", '&', "&"); +} + +void write_benchset_header(out_t& out, const results_vector& results, ssa benchsetName, unsigned id) { + size_t width = 40 / results.size(); + out += "\n\n

" + repl_html_symbols(benchsetName) + "

\n"; + for (const auto& r : results) { + out += ""; + } + out += ""; +} + +void write_benchset_footer(out_t& out, ssa script) { + out += "\n
Benchmark nameComment" + r.platform_ + "
"; +} + +ssa extract_name_result(ssa line, ssa& result) { + size_t ns = line.find(" ns "); + bool inNs = true; + if (ns == str::npos) { + ns = line.find("ERROR OCCURRED: 'not implemented'"); + if (ns == str::npos) { + std::cerr << "Not found ' ns ' in line " << line << std::endl; + throw std::runtime_error{"bad line"}; + } + inNs = false; + } + line.len = ns; + if (inNs) { + size_t end = line.find_last(' '); + result = line(end + 1); + if (auto rp = line.find("/repeats"); rp != str::npos) { + line.len = rp; + } else { + line.len = end; + } + } else { + result = "Not impl"; + } + return line.trimmed_right(); +} + +ssa extract_comment(ssa commentsText, ssa benchmarkName) { + size_t idx = commentsText.find_end(lstringa<120>{"- " + benchmarkName + "\n"}); + if (idx != str::npos) { + if (commentsText[idx] != '\n' && commentsText(idx, 2) != "- ") { + return commentsText.from_to(idx, commentsText.find("\n\n", idx)); + } + } + return stra::empty_str; +} + +void write_one_result(out_t& out, ssa result, ssa line, auto& script_text, bool last) { + out += "" + result + ""; + script_text += e_choice(result[0] == 'N', "NaN", result) + e_choice(last, "]", ","); +} + +ssa extract_source_for_benchmark(ssa benchName, ssa sourceText) { + static hashStrMapA textes; + + size_t delim = benchName.find_last('/'); + if (delim != str::npos && std::get<1>(benchName(delim + 1).to_int()) == IntConvertResult::Success) { + benchName.len = delim; + } + auto [it, not_exist] = textes.try_emplace(benchName); + if (not_exist) { + // Ищем имя функции для этого бенчмарка + size_t start = sourceText.find(lstringa<128>{"->Name(\"" + e_repl(benchName, "\"", "\\\"") + "\")"}); + if (start == str::npos) { + std::cerr << "Can not found benchmark function name for " << benchName << std::endl; + return stra::empty_str; + } + start = sourceText(0, start).find('(', sourceText.find_last('\n', start - 1)); + if (start == str::npos) { + std::cerr << "Can not found benchmark function name for " << benchName << std::endl; + return stra::empty_str; + } + start++; + size_t end = sourceText.find_first_of(")<,", start); + ssa funcName = sourceText.from_to(start, end); + auto [func_it, not_exist] = textes.try_emplace(funcName); + if (not_exist) { + // Теперь ищем саму эту функцию + start = sourceText.find(lstringa<128>{funcName + "(benchmark::State"}); + if (start == str::npos) { + std::cerr << "Can not found source function " << funcName << " for benchmark " << benchName << std::endl; + return stra::empty_str; + } + start = sourceText.find_last('\n', start); + size_t templ_start = sourceText.find_last('\n', start) + 1; + if (sourceText(templ_start).starts_with("template")) { + start = templ_start; + } else { + start++; + } + size_t end = -1; + // Проверим, возможно там есть переход на другую функцию через //> + ssa prevLine = sourceText.from_to(sourceText.find_last('\n', start - 1) + 1, start); + if (prevLine.starts_with("//> ")) { + prevLine.remove_prefix(4); + start = sourceText.find(prevLine); + if (start == str::npos) { + std::cerr << "Not found link " << prevLine; + throw std::runtime_error{"Not found link"}; + } + size_t beginLine = sourceText.find_last('\n', start); + ssa indent = sourceText.from_to(beginLine, start); + end = sourceText.find(lstringa<40>{indent + "}\n"}, start + prevLine.length()); + if (end == str::npos) { + std::cerr << "Not found end of " << prevLine; + throw std::runtime_error{"Not found end of func"}; + } + lstringa<2048> text = expr_replaced{sourceText.from_to(beginLine, end + indent.length() + 1), indent, "\n"}; + func_it->second = repl_html_symbols(text(1)); + } else { + end = sourceText.find("\n}\n", start); + func_it->second = repl_html_symbols(sourceText.from_to(start, end + 2)); + } + } + it->second = func_it->second; + } + return it->second; +} + +void write_benchmarks(out_t& out, const results_vector& results, ssa sourceText, ssa commentsText) { + std::vector> splitters; + splitters.reserve(results.size()); + + for (const auto& r : results) { + splitters.emplace_back(r.current_text_.splitter("\n")); + } + bool needFooter = false, needCommaForTests = false; + lstringa<1024> script_text; + unsigned benchSetId = 0; + while(!splitters[0].is_done()) { + ssa line = splitters[0].next(), benchName, result; + if (auto rm = line.find("_mean"); rm != str::npos) { + benchName = extract_name_result(line, result)(0, rm); + auto source = extract_source_for_benchmark(benchName, sourceText); + auto comment = extract_comment(commentsText, benchName); + // Нужно вывести название бенча и коммент + out += "\n" + + repl_html_symbols(benchName) + + "" + + source + "" + + e_if(!comment.is_empty(), " >> " + comment + "") + + ""; + script_text += e_if(needCommaForTests, "},") + "\n{name:'" + e_repl(benchName.to_str(), "'", "\\'") + "',data:["; + write_one_result(out, result, line, script_text, result.size() == 1); + + for (unsigned idx = 1; idx < results.size(); idx++) { + if (splitters[idx].is_done()) { + std::cerr << "Not expected end of file for " << results[idx].platform_ << std::endl; + throw std::runtime_error{"Not expected end of file"}; + } + line = splitters[idx].next(); + ssa rbench_name = extract_name_result(line, result)(0, rm); + if (rbench_name != benchName) { + while (line.find("_mean") == str::npos && !splitters[idx].is_done()) { + line = splitters[idx].next(); + } + rbench_name = extract_name_result(line, result)(0, rm); + if (rbench_name != benchName) { + std::cerr << "In results for " << results[idx].platform_ << " benchmark '" << rbench_name + << "' does not match with other results" << std::endl; + result = stra::empty_str; + } + } + write_one_result(out, result, line, script_text, idx == results.size() - 1); + } + out += ""; + needCommaForTests = true; + continue; + } else if (line.starts_with("--") && !line.ends_with("---")) { + // Начинается новый набор бенчмарков + if (needFooter) { + write_benchset_footer(out, script_text); + } + benchName = extract_name_result(line, result); + // Из названия набора надо удалить начальные и конечные --- + benchName = benchName.from_to(benchName.find(' ') + 1, benchName.find_last(' ')).trimmed(); + write_benchset_header(out, results, benchName, ++benchSetId); + needFooter = true; + needCommaForTests = false; + script_text = "bench_sets['" + e_repl(benchName.to_str(), "'", "\\'") + "'] = {id:'bs" + benchSetId +"', tests:["; + } + // Эти строки надо пропустить во всех файлах + for (unsigned idx = 1; idx < results.size(); idx++) { + if (splitters[idx].is_done()) { + std::cerr << "Not expected end of file for " << results[idx].platform_ << std::endl; + throw std::runtime_error{"Not expected end of file"}; + } + line = splitters[idx].next(); + } + } + if (needFooter) { + write_benchset_footer(out, script_text); + } +} + +out_t create_page_text() { + auto sourceText = get_file_content("bench_str.cpp"); + auto commentsText = get_file_content("comments.txt"); + + auto resultInfos = get_results_infos(); + out_t out; + out.reserve_no_preserve(64 * 1024); + write_header(out); + write_platforms_cpu(out, resultInfos); + write_benchmarks(out, resultInfos, sourceText, commentsText); + out += ""; + return out; +} + +int main() { + int res = 0; + + try { + auto pageText = create_page_text(); + std::ofstream fout{"results.html", std::ios::binary | std::ios::trunc}; + if (!fout.is_open()) { + throw std::runtime_error{"Can not open file results.html for write results"}; + } + fout.write(pageText.c_str(), pageText.size()); + } catch (const std::exception& err) { + std::cerr << "Catch exception: " << err.what() << "\nProgram exited\n"; + res = -1; + } catch (...) { + std::cerr << "Catch unknown exception.\nProgram exited\n"; + res = -2; + } + return res; +} diff --git a/bench/results.css b/bench/results.css new file mode 100644 index 0000000..fafcb72 --- /dev/null +++ b/bench/results.css @@ -0,0 +1,105 @@ +body { + margin: auto; + font-size: 12pt; +} +h2 { + text-align: center; +} +table { + border: 1px black; + text-align: right; +} +table { + margin: auto; +} +table tr:nth-child(odd) { background: #fff; } +table tr:nth-child(even) { background: #f2f2f2; } + +table th { + text-align: center; +} + +table tr:hover td { + background-color: lightcyan; +} +div.header { + max-width: 960px; + margin: 0 auto; +} + +canvas { + max-width: 2000px; + margin: 0 auto; +} + +.benchset { + max-width: 960px; + padding: 1px; + margin: 5px auto; + border-radius: 3px; + background-color: gainsboro; +} +.benchset h4{ + text-align: left; + padding-left: 20px; +} + +.test_platforms { + margin: auto; +} +.test_platforms ul{ + display: table; +} + +.test_platforms li { + display: table-row; +} + +.test_platforms li:before { + content: "\2022"; + padding-right: 0.5em; +} + +.test_platforms span.tooltip { + padding-left: 20px; + display: table-cell; +} + +span.platform { + display: table-cell; +} +.info { + border-radius: 3px; + border: solid 1px lightgrey; + background-color: beige; + color: brown; +} +.code { + font-family: 'Cascadia Code', Consolas, 'Courier New', Courier, monospace; +} +.tooltip { + position: relative; + display: inline-block; +} +.tooltip .tooltiptext { + visibility: hidden; + background-color: beige; + color: black; + text-align: left; + border-radius: 6px; + padding: 15px; + position: absolute; + z-index: 1; + top: 35px; + right: 0; + white-space: pre; + border: 1px solid darkgray; + box-shadow: 4px 4px 8px 0px rgba(34, 60, 80, 0.2);; + transform: translate(50%); +} +.tooltip:hover .tooltiptext { + visibility: visible; +} +h4 { + text-align: center; +} diff --git a/bench/results.html b/bench/results.html new file mode 100644 index 0000000..0c941d5 --- /dev/null +++ b/bench/results.html @@ -0,0 +1,3769 @@ + + + + + SimStr benchmarks results + + + + +

SimStr benchmarks results

+All times in ns. +Source for benchmarks +
Group tests by platforms in charts:

Test configurations:

    +
  • Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-2132 X 2494.22 MHz CPU sCPU Caches: + L1 Data 32 KiB (x16) + L1 Instruction 32 KiB (x16) + L2 Unified 256 KiB (x16) + L3 Unified 40960 KiB (x1) +Load Average: 0.49, 0.86, 0.76 Include in charts:
  • +
  • Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-1332 X 2494.22 MHz CPU sCPU Caches: + L1 Data 32 KiB (x16) + L1 Instruction 32 KiB (x16) + L2 Unified 256 KiB (x16) + L3 Unified 40960 KiB (x1) +Load Average: 0.00, 0.00, 0.00 Include in charts:
  • +
  • Xeon E5-2682 v4, Windows 10, Clang-1932 X 2518.87 MHz CPU sCPU Caches: + L1 Data 32 KiB (x16) + L1 Instruction 32 KiB (x16) + L2 Unified 256 KiB (x16) + L3 Unified 40960 KiB (x1) Include in charts:
  • +
  • Xeon E5-2682 v4, Windows 10, MSVC-1932 X 2497.21 MHz CPU sCPU Caches: + L1 Data 32 KiB (x16) + L1 Instruction 32 KiB (x16) + L2 Unified 256 KiB (x16) + L3 Unified 40960 KiB (x1) Include in charts:
  • +
  • Xeon E5-2682 v4, WASM Chrome, Clang-2132 X 2513.96 MHz CPU sChrome 136.0.7103.114 webasm Include in charts:
  • +
+ + + +

Create Empty Str

+ + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::string e;template<typename T> +void CreateEmpty(benchmark::State& state) { + for (auto _: state) { + T empty_string; + benchmark::DoNotOptimize(empty_string); + } +} >> Пустые строки, ничего необычного.1.131.191.122.593.47
std::string_view e;template<typename T> +void CreateEmpty(benchmark::State& state) { + for (auto _: state) { + T empty_string; + benchmark::DoNotOptimize(empty_string); + } +}0.3720.7590.3771.863.68
ssa e;template<typename T> +void CreateEmpty(benchmark::State& state) { + for (auto _: state) { + T empty_string; + benchmark::DoNotOptimize(empty_string); + } +}0.3750.1850.3671.842.14
stringa e;template<typename T> +void CreateEmpty(benchmark::State& state) { + for (auto _: state) { + T empty_string; + benchmark::DoNotOptimize(empty_string); + } +}0.7570.7590.7512.223.66
lstringa<20> e;template<typename T> +void CreateEmpty(benchmark::State& state) { + for (auto _: state) { + T empty_string; + benchmark::DoNotOptimize(empty_string); + } +}1.161.111.142.623.10
lstringa<40> e;template<typename T> +void CreateEmpty(benchmark::State& state) { + for (auto _: state) { + T empty_string; + benchmark::DoNotOptimize(empty_string); + } +}1.141.131.152.603.10
+ +

Create Str from short literal (9 symbols)

+ + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::string e = "Test text";template<typename T> +void CreateShortLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string = TEST_TEXT; + benchmark::DoNotOptimize(empty_string); + } +} >> Короткий литерал помещается во внутренний буфер std::string, +время тратится только на копирование 10 байтов.1.881.881.852.614.95
std::string_view e = "Test text";template<typename T> +void CreateShortLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string = TEST_TEXT; + benchmark::DoNotOptimize(empty_string); + } +} >> И string_view, и ssa - по сути одно и то же: +указатель на текст и его длина.0.7460.7570.7401.832.22
ssa e = "Test text";template<typename T> +void CreateShortLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string = TEST_TEXT; + benchmark::DoNotOptimize(empty_string); + } +}0.3770.7460.3711.842.18
stringa e = "Test text";template<typename T> +void CreateShortLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string = TEST_TEXT; + benchmark::DoNotOptimize(empty_string); + } +} >> stringa при инициализации константным литералом так же +сохраняет только указатель на текст и его длину.1.121.121.122.604.69
lstringa<20> e = "Test text";template<typename T> +void CreateShortLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string = TEST_TEXT; + benchmark::DoNotOptimize(empty_string); + } +} >> Внутреннего буфера хватает для размещения символов, +время уходит только на копирование байтов.1.891.871.842.256.54
lstringa<40> e = "Test text";template<typename T> +void CreateShortLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string = TEST_TEXT; + benchmark::DoNotOptimize(empty_string); + } +}1.901.911.872.634.02
+ +

Create Str from long literal (30 symbols)

+ + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::string e = "123456789012345678901234567890";template<typename T> +void CreateLongLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string{LONG_TEXT}; + benchmark::DoNotOptimize(empty_string); + } +} >> Вот тут уже литерал не помещается во внутренний буфер, +возникает аллокация и копирование 30-и байтов. +Но как же отстает аллокация под Windows от Linux'а, 20 vs 70 ns...19.518.778.074.856.3
std::string_view e = "123456789012345678901234567890";template<typename T> +void CreateLongLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string{LONG_TEXT}; + benchmark::DoNotOptimize(empty_string); + } +} >> string_view и ssa по прежнему ничего не делают, кроме +запоминания указателя на текст и его размера.0.7580.7510.7391.845.05
ssa e = "123456789012345678901234567890";template<typename T> +void CreateLongLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string{LONG_TEXT}; + benchmark::DoNotOptimize(empty_string); + } +}0.3760.7540.3691.852.18
stringa e = "123456789012345678901234567890";template<typename T> +void CreateLongLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string{LONG_TEXT}; + benchmark::DoNotOptimize(empty_string); + } +} >> stringa на константных литералах не отстает!1.131.131.112.925.33
lstringa<20> e = "123456789012345678901234567890";template<typename T> +void CreateLongLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string{LONG_TEXT}; + benchmark::DoNotOptimize(empty_string); + } +} >> lstringa<20> может вместить в себя до 23 символов, +Очевидно, что для 30-и символов уже нужна аллокация.20.519.682.076.759.7
lstringa<40> e = "123456789012345678901234567890";template<typename T> +void CreateLongLiteral(benchmark::State& state) { + for (auto _: state) { + T empty_string{LONG_TEXT}; + benchmark::DoNotOptimize(empty_string); + } +} >> А в lstringa<40> влезает до 47 символов, так что просто +копируется 30 байтов.1.902.591.853.016.28
+ +

Create copy of Str with 9 symbols

+ + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::string e = "Test text"; auto c{e};template<typename T> +void CopyShortString(benchmark::State& state) { + T x{TEST_TEXT}; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> Строка в пределах SSO, так что просто копирует байты.5.734.911.875.165.67
std::string_view e = "Test text"; auto c{e};template<typename T> +void CopyShortString(benchmark::State& state) { + T x{TEST_TEXT}; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}0.3810.3770.3763.745.04
ssa e = "Test text"; auto c{e};template<typename T> +void CopyShortString(benchmark::State& state) { + T x{TEST_TEXT}; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> ssa и string_view не владеют строкой, копируется +только информация о строке.0.3760.3780.3773.755.02
stringa e = "Test text"; auto c{e};template<typename T> +void CopyShortString(benchmark::State& state) { + T x{TEST_TEXT}; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> Копирование stringa происходит быстро, +особенно если она инициализирована литералом.1.121.141.324.074.81
lstringa<20> e = "Test text"; auto c{e};template<typename T> +void CopyShortString(benchmark::State& state) { + T x{TEST_TEXT}; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> В обоих случаях хватает внутреннего буфера.5.004.845.238.6415.8
lstringa<40> e = "Test text"; auto c{e};template<typename T> +void CopyShortString(benchmark::State& state) { + T x{TEST_TEXT}; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> Только копируются байты.4.624.605.248.4615.7
+ +

Create copy of Str with 30 symbols

+ + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::string e = "123456789012345678901234567890"; auto c{e};template<typename T> +void CopyLongString(benchmark::State& state) { + T x = LONG_TEXT; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + } +} >> Копирования длинной строки вызывает аллокацию, +SSO уже не хватает. И снова как же отстаёт аллокация под Windows...19.824.278.276.3116
std::string_view e = "123456789012345678901234567890"; auto c{e};template<typename T> +void CopyLongString(benchmark::State& state) { + T x = LONG_TEXT; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + } +}0.7630.7460.7411.845.04
ssa e = "123456789012345678901234567890"; auto c{e};template<typename T> +void CopyLongString(benchmark::State& state) { + T x = LONG_TEXT; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + } +}0.3730.7440.3721.872.20
stringa e = "123456789012345678901234567890"; auto c{e};template<typename T> +void CopyLongString(benchmark::State& state) { + T x = LONG_TEXT; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + } +} >> А вот у stringa копирование литерала не зависит от его длины, +сравни с предыдущим бенчмарком.1.141.131.892.975.36
lstringa<20> e = "123456789012345678901234567890"; auto c{e};template<typename T> +void CopyLongString(benchmark::State& state) { + T x = LONG_TEXT; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + } +} >> Не влезает, аллокация.20.224.479.082.067.1
lstringa<40> e = "123456789012345678901234567890"; auto c{e};template<typename T> +void CopyLongString(benchmark::State& state) { + T x = LONG_TEXT; + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + } +} >> Уложили во внутренний буфер.4.685.624.957.0515.5
+ +

Find 9 symbols text in end of 99 symbols text

+ + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::string::find;template<typename T> +void Find(benchmark::State& state) { + T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT}; + for (auto _: state) { + int i = (int)x.find(TEST_TEXT); + #ifdef CHECK_RESULT + if (i != 90) { + state.SkipWithError("not find?"); + break; + } + #endif + benchmark::DoNotOptimize(i); + benchmark::DoNotOptimize(x); + } +} >> Здесь "победила дружба", у всех типов по колонке примерно одинаково. +Однако, Windows и Linux явно в разных весовых категориях.7.737.1139.542.5141
std::string_view::find;template<typename T> +void Find(benchmark::State& state) { + T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT}; + for (auto _: state) { + int i = (int)x.find(TEST_TEXT); + #ifdef CHECK_RESULT + if (i != 90) { + state.SkipWithError("not find?"); + break; + } + #endif + benchmark::DoNotOptimize(i); + benchmark::DoNotOptimize(x); + } +}7.256.4339.141.5134
ssa::find;template<typename T> +void Find(benchmark::State& state) { + T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT}; + for (auto _: state) { + int i = (int)x.find(TEST_TEXT); + #ifdef CHECK_RESULT + if (i != 90) { + state.SkipWithError("not find?"); + break; + } + #endif + benchmark::DoNotOptimize(i); + benchmark::DoNotOptimize(x); + } +}6.916.4718.221.1101
stringa::find;template<typename T> +void Find(benchmark::State& state) { + T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT}; + for (auto _: state) { + int i = (int)x.find(TEST_TEXT); + #ifdef CHECK_RESULT + if (i != 90) { + state.SkipWithError("not find?"); + break; + } + #endif + benchmark::DoNotOptimize(i); + benchmark::DoNotOptimize(x); + } +}8.106.8318.832.2102
lstringa<20>::find;template<typename T> +void Find(benchmark::State& state) { + T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT}; + for (auto _: state) { + int i = (int)x.find(TEST_TEXT); + #ifdef CHECK_RESULT + if (i != 90) { + state.SkipWithError("not find?"); + break; + } + #endif + benchmark::DoNotOptimize(i); + benchmark::DoNotOptimize(x); + } +}6.916.8818.221.3100
lstringa<40>::find;template<typename T> +void Find(benchmark::State& state) { + T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT}; + for (auto _: state) { + int i = (int)x.find(TEST_TEXT); + #ifdef CHECK_RESULT + if (i != 90) { + state.SkipWithError("not find?"); + break; + } + #endif + benchmark::DoNotOptimize(i); + benchmark::DoNotOptimize(x); + } +}6.926.8017.821.6102
+ +

Copy not literal Str with N symbols

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::string copy{str_with_len_N};/15template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}5.877.341.855.18117
std::string copy{str_with_len_N};/16template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> Явно виден скачок, где заканчивается SSO и начинается аллокация. +Обратите внимание, что WASM - 32-битный, и там размер +SSO у std::string меньше, насколько я помню, 11 символов + 0.23.524.880.484.9120
std::string copy{str_with_len_N};/23template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> Дальше просто добавляется время на копирование байтов.23.625.381.285.1119
std::string copy{str_with_len_N};/24template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}23.724.680.983.1120
std::string copy{str_with_len_N};/32template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}23.123.985.989.1124
std::string copy{str_with_len_N};/64template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}23.124.187.189.7125
std::string copy{str_with_len_N};/128template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}25.426.190.389.0122
std::string copy{str_with_len_N};/256template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}25.526.687.891.5146
std::string copy{str_with_len_N};/512template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}30.430.890.493.8163
std::string copy{str_with_len_N};/1024template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}39.041.295.599.5148
std::string copy{str_with_len_N};/2048template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}111111130132165
std::string copy{str_with_len_N};/4096template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> Чем длиннее строка, тем дольше создаётся копия.142139186181204
stringa copy{str_with_len_N};/15template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> Здесь stringa инициализируется не литералом, +а значит, должна сама хранить символы.1.131.111.314.154.84
stringa copy{str_with_len_N};/16template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> Под WASM SSO у stringa составляет 15 символов. Кроме того, +собиралось без поддержки потоков, поэтому возможно атомарный +инкремент заменён на обычный, судя по времени.1.121.121.314.1110.3
stringa copy{str_with_len_N};/23template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> SSO в stringa до 23 символов, и даже 23 +копируются быстрее, чем 15 в std::string.1.121.111.304.1310.1
stringa copy{str_with_len_N};/24template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> Всё, не влезаем в SSO, а значит, используем shared буфер. +Добавляется время на атомарный инкремент счётчика.16.316.216.118.710.2
stringa copy{str_with_len_N};/32template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}16.416.216.318.610.2
stringa copy{str_with_len_N};/64template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}16.316.816.018.610.0
stringa copy{str_with_len_N};/128template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}16.616.316.118.610.1
stringa copy{str_with_len_N};/256template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}16.316.316.018.610.1
stringa copy{str_with_len_N};/512template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}16.316.416.018.710.1
stringa copy{str_with_len_N};/1024template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}16.316.216.018.610.0
stringa copy{str_with_len_N};/2048template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}16.416.216.018.810.0
stringa copy{str_with_len_N};/4096template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> И как видно, кроме инкремента нет накладных расходов, +время копирования не зависит от длины строки.16.316.216.018.510.1
lstringa<16> copy{str_with_len_N};/15template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> lstringa<16> использует SSO до 23 символов. +А в WASM 32-битная архитектура, SSO до 19 символов.5.114.874.858.6715.7
lstringa<16> copy{str_with_len_N};/16template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}5.124.834.838.6116.1
lstringa<16> copy{str_with_len_N};/23template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}5.204.904.898.5875.4
lstringa<16> copy{str_with_len_N};/24template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> И после начинает вести себя при копировании, как std::string.24.325.083.580.576.2
lstringa<16> copy{str_with_len_N};/32template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}23.925.085.883.182.1
lstringa<16> copy{str_with_len_N};/64template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}25.825.981.483.178.1
lstringa<16> copy{str_with_len_N};/128template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}26.327.084.386.579.2
lstringa<16> copy{str_with_len_N};/256template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}27.728.385.189.8103
lstringa<16> copy{str_with_len_N};/512template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}30.630.789.090.8121
lstringa<16> copy{str_with_len_N};/1024template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}85.983.799.5101107
lstringa<16> copy{str_with_len_N};/2048template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}99.297.7132131123
lstringa<16> copy{str_with_len_N};/4096template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}118116195192160
lstringa<512> copy{str_with_len_N};/15template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}4.964.995.578.4715.3
lstringa<512> copy{str_with_len_N};/16template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}4.954.895.698.5915.1
lstringa<512> copy{str_with_len_N};/23template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}4.914.895.608.4815.6
lstringa<512> copy{str_with_len_N};/24template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}4.924.855.598.6015.3
lstringa<512> copy{str_with_len_N};/32template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}4.614.528.4811.717.2
lstringa<512> copy{str_with_len_N};/64template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}6.146.158.7411.618.3
lstringa<512> copy{str_with_len_N};/128template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}6.506.598.9911.919.1
lstringa<512> copy{str_with_len_N};/256template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}8.198.2910.113.032.3
lstringa<512> copy{str_with_len_N};/512template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> Даже 512 символов копируются быстрее, чем +одна аллокация или атомарный инкремент.10.410.611.814.633.8
lstringa<512> copy{str_with_len_N};/1024template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +} >> А дальше уже как у всех87.089.099.4101106
lstringa<512> copy{str_with_len_N};/2048template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}103101133130119
lstringa<512> copy{str_with_len_N};/4096template<typename T> +void CopyDynString(benchmark::State& state) { + T x(state.range(0), 'a'); + for (auto _: state) { + T copy{x}; + benchmark::DoNotOptimize(copy); + benchmark::DoNotOptimize(x); + } +}118115196192162
+ +

Convert to int '1234567'

+ + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);void ToIntStr10(benchmark::State& state, const std::string& s, int c) { + for (auto _: state) { + int res = std::strtol(s.c_str(), nullptr, 10); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(s); + } +} >> В simstr для конвертации в число достаточно куска строки, +нет нужды в null терминированности. Ближайший аналог такого +поведения "std::from_chars", но он к сожалению очень ограничен +по возможностям. Здесь я попытался произвести тесты, близкие по +логике к работе std::from_chars27.527.332.533.7205
std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);void ToIntFromChars10(benchmark::State& state, const std::string_view& s, int c) { +#ifdef __EMSCRIPTEN__ + state.SkipWithError("not implemented"); +#else + for (auto _: state) { + int res = 0; + std::from_chars(s.data(), s.data() + s.size(), res, 10); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(s); + } +#endif +} >> from_chars требует точного указания основания счисления, +не допускает знаков плюс, пробелов, префиксов 0x и т.п.15.212.413.817.9Not impl
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>template<typename T> +void ToIntSimStr10(benchmark::State& state, T t, int c) { + for (auto _: state) { + int res = std::get<0>(t. template to_int<int, true, 10, false, false>()); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(t); + } +} >> Здесь для to_int заданы такие же ограничения - проверять переполнение, +десятичная система, без лидирующих пробелов и знака плюс13.77.9213.315.455.2
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>template<typename T> +void ToIntSimStr10(benchmark::State& state, T t, int c) { + for (auto _: state) { + int res = std::get<0>(t. template to_int<int, true, 10, false, false>()); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(t); + } +}13.27.7313.015.151.0
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>template<typename T> +void ToIntSimStr10(benchmark::State& state, T t, int c) { + for (auto _: state) { + int res = std::get<0>(t. template to_int<int, true, 10, false, false>()); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(t); + } +}12.87.7313.214.952.1
+ +

Convert to unsigned 'abcDef'

+ + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);void ToIntStr16(benchmark::State& state, const std::string& s, int c) { + for (auto _: state) { + int res = std::strtol(s.c_str(), nullptr, 16); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(s); + } +} >> Всё то же, только для 16ричной системы24.224.034.436.1149
std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);void ToIntFromChars16(benchmark::State& state, const std::string_view& s, int c) { +#ifdef __EMSCRIPTEN__ + state.SkipWithError("not implemented"); +#else + for (auto _: state) { + int res = 0; + std::from_chars(s.data(), s.data() + s.size(), res, 16); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(s); + } +#endif +}9.8014.88.2910.1Not impl
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>template<typename T> +void ToIntSimStr16(benchmark::State& state, T t, int c) { + for (auto _: state) { + int res = std::get<0>(t. template to_int<int, true, 16, false, false>()); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(t); + } +}11.87.5511.413.851.8
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>template<typename T> +void ToIntSimStr16(benchmark::State& state, T t, int c) { + for (auto _: state) { + int res = std::get<0>(t. template to_int<int, true, 16, false, false>()); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(t); + } +}11.68.2810.812.850.0
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>template<typename T> +void ToIntSimStr16(benchmark::State& state, T t, int c) { + for (auto _: state) { + int res = std::get<0>(t. template to_int<int, true, 16, false, false>()); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(t); + } +}11.58.1611.212.851.4
+ +

Convert to int ' 1234567'

+ + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);void ToIntStr0(benchmark::State& state, const std::string& s, int c) { + for (auto _: state) { + int res = std::strtol(s.c_str(), nullptr, 0); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(s); + } +} >> А здесь уже парсинг произвольного числа.29.129.144.248.8216
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflowtemplate<typename T> +void ToIntSimStr0(benchmark::State& state, T t, int c) { + for (auto _: state) { + int res = std::get<0>(t. template to_int<int>()); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(t); + } +}22.116.718.822.474.8
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflowvoid ToIntNoOverflow(benchmark::State& state, ssa t, int c) { + for (auto _: state) { + int res = std::get<0>(t.to_int<int, false>()); + #ifdef CHECK_RESULT + if (res != c) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(res); + benchmark::DoNotOptimize(t); + } +}15.814.615.919.051.3
+ +

Append const literal of 16 bytes 64 times, 1024 total length

+ + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::stringstream str; ... str << "abbaabbaabbaabba";void AppendStreamConstLiteral(benchmark::State& state) { + for (auto _: state) { + std::string result; + std::stringstream str; + for (size_t c = 0; c < 64; c++) { + str << TEXT_16; + } + result = str.str(); + #ifdef CHECK_RESULT + if (result.size() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(str); + } +}138414397392575811603
std::string str; ... str += "abbaabbaabbaabba";void AppendStdStringConstLiteral(benchmark::State& state) { + for (auto _: state) { + std::string result; + for (size_t c = 0; c < 64; c++) { + result += TEXT_16; + } + #ifdef CHECK_RESULT + if (result.size() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + } +}368369106813271138
lstringa<8> str; ... str += "abbaabbaabbaabba";template<unsigned N> +void AppendLstringConstLiteral(benchmark::State& state) { + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 64; c++) { + result += TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + } +}3703727579721204
lstringa<128> str; ... str += "abbaabbaabbaabba";template<unsigned N> +void AppendLstringConstLiteral(benchmark::State& state) { + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 64; c++) { + result += TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + } +} >> Чем больше внутренний буфер, тем меньше раз требуется +аллокация, тем быстрее результат.254258403539873
lstringa<512> str; ... str += "abbaabbaabbaabba";template<unsigned N> +void AppendLstringConstLiteral(benchmark::State& state) { + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 64; c++) { + result += TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + } +}232241229371640
lstringa<1024> str; ... str += "abbaabbaabbaabba";template<unsigned N> +void AppendLstringConstLiteral(benchmark::State& state) { + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 64; c++) { + result += TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + } +}140140139235498
+ +

Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length

+ + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::stringstream str; ... str << str_var << "abbaabbaabbaabba";void AppendStreamStrConstLiteral(benchmark::State& state) { + std::string s1 = TEXT_16; + for (auto _: state) { + std::string result; + std::stringstream s; + for (size_t c = 0; c < 32; c++) { + s << s1 << TEXT_16; + } + result = s.str(); + #ifdef CHECK_RESULT + if (result.size() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + } +}139013996632598611698
std::string str; ... str += str_var + "abbaabbaabbaabba";void AppendStdStrStrConstLiteral(benchmark::State& state) { + std::string p1 = TEXT_16; + for (auto _: state) { + std::string result; + for (size_t c = 0; c < 32; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.size() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +}12981343390139294015
lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";template<unsigned N> +void AppendLstringStrConstLiteral(benchmark::State& state) { + stringa p1 = TEXT_16; + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 32; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +}4254297638491435
lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";template<unsigned N> +void AppendLstringStrConstLiteral(benchmark::State& state) { + stringa p1 = TEXT_16; + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 32; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +}3673614815501128
lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";template<unsigned N> +void AppendLstringStrConstLiteral(benchmark::State& state) { + stringa p1 = TEXT_16; + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 32; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +}323316306388858
lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";template<unsigned N> +void AppendLstringStrConstLiteral(benchmark::State& state) { + stringa p1 = TEXT_16; + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 32; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +}241256214271730
+ +

Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length

+ + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 timesvoid AppendStreamStrConstLiteralBig(benchmark::State& state) { + std::string s1 = TEXT_16; + for (auto _: state) { + std::string result; + std::stringstream s; + for (size_t c = 0; c < 2048; c++) { + s << s1 << TEXT_16; + } + result = s.str(); + #ifdef CHECK_RESULT + if (result.size() != 1024 * 64) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + } +}7390874700361900285644581542
std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 timesvoid AppendStdStrStrConstLiteralBig(benchmark::State& state) { + std::string p1 = TEXT_16; + for (auto _: state) { + std::string result; + for (size_t c = 0; c < 2048; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.size() != 1024 * 64) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +}7772272474199378194551207680
lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 timestemplate<unsigned N> +void AppendLstringStrConstLiteralBig(benchmark::State& state) { + stringa p1 = TEXT_16; + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 2048; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024 * 64) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +}2111219642198522361552577
lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 timestemplate<unsigned N> +void AppendLstringStrConstLiteralBig(benchmark::State& state) { + stringa p1 = TEXT_16; + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 2048; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024 * 64) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +}1612417774182152228049889
lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 timestemplate<unsigned N> +void AppendLstringStrConstLiteralBig(benchmark::State& state) { + stringa p1 = TEXT_16; + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 2048; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024 * 64) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +}1612917565179732233550097
lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 timestemplate<unsigned N> +void AppendLstringStrConstLiteralBig(benchmark::State& state) { + stringa p1 = TEXT_16; + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 2048; c++) { + result += p1 + TEXT_16; + } + #ifdef CHECK_RESULT + if (result.length() != 1024 * 64) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(p1); + } +}1614518274178912166349930
+ +

Append 2 string of 16 bytes 32 times, 1024 total length

+ + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::stringstream str; ... str << str_var1 << str_var2;void AppendStream2String(benchmark::State& state) { + std::string s1 = TEXT_16; + std::string s2 = TEXT_16; + for (auto _: state) { + std::string result; + std::stringstream s; + for (size_t c = 0; c < 32; c++) { + s << s1 << s2; + } + result = s.str(); + #ifdef CHECK_RESULT + if (result.size() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + benchmark::DoNotOptimize(s2); + } +}139314006383549111739
std::string str; ... str += str_var1 + str_var2;void AppendStdStr2String(benchmark::State& state) { + std::string s1 = TEXT_16; + std::string s2 = TEXT_16; + + for (auto _: state) { + std::string result; + for (size_t c = 0; c < 32; c++) { + result += s1 + s2; + } + #ifdef CHECK_RESULT + if (result.size() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + benchmark::DoNotOptimize(s2); + } +}14121342398639974587
lstringa<16> str; ... str += str_var1 + str_var2;template<unsigned N> +void AppendLstring2String(benchmark::State& state) { + stra s1 = TEXT_16; + stra s2 = TEXT_16; + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 32; c++) { + result += s1 + s2; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + benchmark::DoNotOptimize(s2); + } +}5135988599581593
lstringa<128> str; ... str += str_var1 + str_var2;template<unsigned N> +void AppendLstring2String(benchmark::State& state) { + stra s1 = TEXT_16; + stra s2 = TEXT_16; + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 32; c++) { + result += s1 + s2; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + benchmark::DoNotOptimize(s2); + } +}4435005696641343
lstringa<512> str; ... str += str_var1 + str_var2;template<unsigned N> +void AppendLstring2String(benchmark::State& state) { + stra s1 = TEXT_16; + stra s2 = TEXT_16; + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 32; c++) { + result += s1 + s2; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + benchmark::DoNotOptimize(s2); + } +}3954624034831057
lstringa<1024> str; ... str += str_var1 + str_var2;template<unsigned N> +void AppendLstring2String(benchmark::State& state) { + stra s1 = TEXT_16; + stra s2 = TEXT_16; + for (auto _: state) { + lstringa<N> result; + for (size_t c = 0; c < 32; c++) { + result += s1 + s2; + } + #ifdef CHECK_RESULT + if (result.length() != 1024) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(s1); + benchmark::DoNotOptimize(s2); + } +}312431314381929
+ +

Append text, number, text

+ + + + + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::stringstream str; str << "test = " << k << " times";void AppendStreamStrNumStr(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + std::stringstream t; + t << "test = " << k << " times"; + std::string result = t.str(); + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +}31333419116631161519990
std::string str = "test = " + std::to_string(k) + " times";void AppendStdStringStrNumStr(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + std::string result = "test = " + std::to_string(k) + " times"; + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +}486451111412603781
char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;void AppendSprintfStrNumStr(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + char buf[100]; + std::sprintf(buf, "test = %u times", k); + std::string result = buf; + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +}14241509290628558018
std::string str = std::format("test = {} times", k);void AppendFormatStrNumStr(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + std::string result = std::format("test = {} times", k); + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +}11841286195024205058
lstringa<8> str; str.format("test = {} times", k);template<typename T> +void AppendSimStrStrNumStrF(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + T result; + result.format("test = {} times", k); + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +} >> В simstr format с первого раза не помещается в такую строку без аллокации.14121618211226097141
lstringa<32> str; str.format("test = {} times", k);template<typename T> +void AppendSimStrStrNumStrF(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + T result; + result.format("test = {} times", k); + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +} >> А в такую помещается. Используйте сразу буфера подходящего размера.9971132102915495041
lstringa<8> str = "test = " + k + " times";template<typename T> +void AppendSimStrStrNumStr(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + T result = "test = "_ss + k + " times"; + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +} >> Результат не помещается в SSO, возникает аллокация.3233168239491865
lstringa<32> str = "test = " + k + " times";template<typename T> +void AppendSimStrStrNumStr(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + T result = "test = "_ss + k + " times"; + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +} >> А здесь и ниже - результат укладывается в SSO. +Ещё раз - используйте сразу буфера подходящего размера.1571621601911202
stringa str = "test = " + k + " times";template<typename T> +void AppendSimStrStrNumStr(benchmark::State& state) { + for (auto _: state) { + for (unsigned k = 1; k <= 1'000'000'000; k *= 10) { + T result = "test = "_ss + k + " times"; + #ifdef CHECK_RESULT + if (!result.starts_with("test = ") || !result.ends_with(" times")) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(k); + } + } +} >> Под WASM размер SSO 15 символов, что явно не хватает для размещения +результата, отсюда и такое время.1521741562411715
+ +

Split text and convert to int

+ + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
std::string::find + substr + std::strtolvoid SplitConvertIntStdString(benchmark::State& state) { + std::string numbers = NUMBER_LIST; + for (auto _: state) { + int total = 0; + for (size_t start = 0; start < numbers.length(); ) { + int delim = numbers.find("-!-", start); + if (delim == std::string::npos) { + delim = numbers.size(); + } + std::string part = numbers.substr(start, delim - start); + total += std::strtol(part.c_str(), nullptr, 0); + start = delim + 3; + } + #ifdef CHECK_RESULT + if (total != 218) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(total); + benchmark::DoNotOptimize(numbers); + } +}2682855765551618
ssa::splitter + ssa::as_intvoid SplitConvertIntSimStr(benchmark::State& state) { + stra numbers = NUMBER_LIST; + for (auto _: state) { + int total = 0; + for (auto splitter = numbers.splitter("-!-"); !splitter.is_done();) { + total += splitter.next().as_int<int>(); + } + #ifdef CHECK_RESULT + if (total != 218) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(total); + benchmark::DoNotOptimize(numbers); + } +}161139173289655
ssa::splitf + functorvoid SplitConvertIntSplitf(benchmark::State& state) { + stra numbers = NUMBER_LIST; + for (auto _: state) { + int total = 0; + numbers.splitf<void>("-!-", [&](ssa& part){total += part.as_int<int>();}); + #ifdef CHECK_RESULT + if (total != 218) { + state.SkipWithError("not equal"); + break; + } + #endif + benchmark::DoNotOptimize(total); + benchmark::DoNotOptimize(numbers); + } +}180153188207899
+ +

Replace symbols in text ~400 symbols

+ + + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
Naive (and wrong) replace symbols with std::string find + replacevoid ReplaceSymbolsStdStringNaiveWrong(benchmark::State& state) { + std::string_view source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + ; + std::vector<std::pair<u8s, std::string_view>> repl = { + {'&', "&amp;"}, + {'-', ""}, + {'<', "&lt;"}, + {'>', "&gt;"}, + {'\'', "&#39;"}, + {'\"', "&quot;"} + }; + + auto repl_all = [](std::string& str, char s, std::string_view repl) { + size_t start_pos = 0; + while((start_pos = str.find(s, start_pos)) != std::string::npos) { + str.replace(start_pos, 1, repl); + start_pos += repl.length(); + } + }; + for (auto _: state) { + std::string result{source}; + for (const auto& r : repl) { + repl_all(result, r.first, r.second); + } +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +} >> Это наивная реализация, которая неверно отработает на +таких заменах, как 'a'->'b' и 'b'->'a'. Но если замены не конфликтуют, +то работает быстро.859867115313036193
replace symbols with std::string find_first_of + replacevoid ReplaceSymbolsStdStringNaiveRight(benchmark::State& state) { + std::string_view source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + ; + std::vector<std::pair<u8s, std::string_view>> repl = { + {'-', ""}, + {'<', "&lt;"}, + {'>', "&gt;"}, + {'\'', "&#39;"}, + {'\"', "&quot;"}, + {'&', "&amp;"}, + }; + + for (auto _: state) { + std::string result{source}; + std::string pattern; + for (const auto& r : repl) { + pattern += r.first; + } + size_t start_pos = 0; + while((start_pos = result.find_first_of(pattern, start_pos)) != std::string::npos) { + size_t idx = pattern.find(result[start_pos]); + result.replace(start_pos, 1, repl[idx].second); + start_pos += repl[idx].second.length(); + } +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +} >> Дальше уже правильные реализации, не зависящие от конфликтующих замен.25412597207322059978
replace symbols with std::string_view find_first_of + copyvoid ReplaceSymbolsStdString(benchmark::State& state) { + std::string_view source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + ; + + const std::string_view repl_from = "-<>'\"&"; + const std::string_view repl_to[] = {"", "&lt;", "&gt;", "&#39;", "&quot;", "&amp;"}; + + for (auto _: state) { + std::string result; + + for (size_t start = 0; start < source.size();) { + size_t idx = source.find_first_of(repl_from, start); + if (idx == std::string::npos) { + result += source.substr(start); + break; + } + if (idx > start) { + result += source.substr(start, idx - start); + } + size_t what = repl_from.find(source[idx]); + result += repl_to[what]; + + start = idx + 1; + } +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl_from); + benchmark::DoNotOptimize(repl_to); + } +}271926712441262510198
replace runtime symbols with string expressions and without remembering all search resultstemplate<bool UseVector> +void ReplaceSymbolsDynPatternSimStr(benchmark::State& state) { + stra source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + ; + + std::vector<std::pair<u8s, ssa>> repl = { + {'-', ""}, + {'<', "&lt;"}, + {'>', "&gt;"}, + {'\'', "&#39;"}, + {'\"', "&quot;"}, + {'&', "&amp;"}, + }; + + for (auto _: state) { + stringa result = expr_replace_symbols<u8s, UseVector>{source, repl}; + +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +}12531543138615555706
replace runtime symbols with simstr and memorization of all search resultstemplate<bool UseVector> +void ReplaceSymbolsDynPatternSimStr(benchmark::State& state) { + stra source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + ; + + std::vector<std::pair<u8s, ssa>> repl = { + {'-', ""}, + {'<', "&lt;"}, + {'>', "&gt;"}, + {'\'', "&#39;"}, + {'\"', "&quot;"}, + {'&', "&amp;"}, + }; + + for (auto _: state) { + stringa result = expr_replace_symbols<u8s, UseVector>{source, repl}; + +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +}10261181137313825029
replace const symbols with string expressions and without remembering all search resultstemplate<bool UseVector> +void ReplaceSymbolsCons2PatternSimStr(benchmark::State& state) { + stra source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + ; + + for (auto _: state) { + stringa result = e_repl_const_symbols<UseVector>(source, + '-', "", + '<', "&lt;", + '>', "&gt;", + '\'', "&#39;", + '\"', "&quot;", + '&', "&amp;" + ); + +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}11501265121312774946
replace const symbols with string expressions and memorization of all search resultstemplate<bool UseVector> +void ReplaceSymbolsCons2PatternSimStr(benchmark::State& state) { + stra source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + " ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf" + ; + + for (auto _: state) { + stringa result = e_repl_const_symbols<UseVector>(source, + '-', "", + '<', "&lt;", + '>', "&gt;", + '\'', "&#39;", + '\"', "&quot;", + '&', "&amp;" + ); + +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + " ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}897866122812664198
+ +

Replace symbols in text ~40 symbols

+ + + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
Short Naive (and wrong) replace symbols with std::string find + replacevoid ShortReplaceSymbolsStdStringNaiveWrong(benchmark::State& state) { + std::string_view source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ; + std::vector<std::pair<u8s, std::string_view>> repl = { + {'&', "&amp;"}, + {'-', ""}, + {'<', "&lt;"}, + {'>', "&gt;"}, + {'\'', "&#39;"}, + {'\"', "&quot;"} + }; + + auto repl_all = [](std::string& str, char s, std::string_view repl) { + size_t start_pos = 0; + while((start_pos = str.find(s, start_pos)) != std::string::npos) { + str.replace(start_pos, 1, repl); + start_pos += repl.length(); + } + }; + for (auto _: state) { + std::string result{source}; + for (const auto& r : repl) { + repl_all(result, r.first, r.second); + } +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +}1651703213291016
Short replace symbols with std::string find_first_of + replacevoid ShortReplaceSymbolsStdStringNaiveRight(benchmark::State& state) { + std::string_view source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ; + std::vector<std::pair<u8s, std::string_view>> repl = { + {'-', ""}, + {'<', "&lt;"}, + {'>', "&gt;"}, + {'\'', "&#39;"}, + {'\"', "&quot;"}, + {'&', "&amp;"}, + }; + + for (auto _: state) { + std::string result{source}; + std::string pattern; + for (const auto& r : repl) { + pattern += r.first; + } + size_t start_pos = 0; + while((start_pos = result.find_first_of(pattern, start_pos)) != std::string::npos) { + size_t idx = pattern.find(result[start_pos]); + result.replace(start_pos, 1, repl[idx].second); + start_pos += repl[idx].second.length(); + } +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +}3123483784291431
Short replace symbols with std::string_view find_first_of + copyvoid ShortReplaceSymbolsStdString(benchmark::State& state) { + std::string_view source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ; + + const std::string_view repl_from = "-<>'\"&"; + const std::string_view repl_to[] = {"", "&lt;", "&gt;", "&#39;", "&quot;", "&amp;"}; + + for (auto _: state) { + std::string result; + + for (size_t start = 0; start < source.size();) { + size_t idx = source.find_first_of(repl_from, start); + if (idx == std::string::npos) { + result += source.substr(start); + break; + } + if (idx > start) { + result += source.substr(start, idx - start); + } + size_t what = repl_from.find_first_of(source[idx]); + result += repl_to[what]; + + start = idx + 1; + } +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl_from); + benchmark::DoNotOptimize(repl_to); + } +}3383223423631417
Short replace runtime symbols with string expressions and without remembering all search resultstemplate<bool UseVector> +void ShortReplaceSymbolsDynPatternSimStr(benchmark::State& state) { + stra source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ; + + std::vector<std::pair<u8s, ssa>> repl = { + {'-', ""}, + {'<', "&lt;"}, + {'>', "&gt;"}, + {'\'', "&#39;"}, + {'\"', "&quot;"}, + {'&', "&amp;"}, + }; + + for (auto _: state) { + stringa result = expr_replace_symbols<u8s, UseVector>{source, repl}; + +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +}165198251279795
Short replace runtime symbols with simstr and memorization of all search resultstemplate<bool UseVector> +void ShortReplaceSymbolsDynPatternSimStr(benchmark::State& state) { + stra source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ; + + std::vector<std::pair<u8s, ssa>> repl = { + {'-', ""}, + {'<', "&lt;"}, + {'>', "&gt;"}, + {'\'', "&#39;"}, + {'\"', "&quot;"}, + {'&', "&amp;"}, + }; + + for (auto _: state) { + stringa result = expr_replace_symbols<u8s, UseVector>{source, repl}; + +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(repl); + } +}188192347389847
Short replace const symbols with string expressions and without remembering all search resultstemplate<bool UseVector> +void ShortReplaceSymbolsCons2PatternSimStr(benchmark::State& state) { + stra source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ; + + for (auto _: state) { + stringa result = e_repl_const_symbols<UseVector>(source, + '-', "", + '<', "&lt;", + '>', "&gt;", + '\'', "&#39;", + '\"', "&quot;", + '&', "&amp;" + ); + +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}146165218248626
Short replace const symbols with string expressions and memorization of all search resultstemplate<bool UseVector> +void ShortReplaceSymbolsCons2PatternSimStr(benchmark::State& state) { + stra source = + "abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >" + ; + + for (auto _: state) { + stringa result = e_repl_const_symbols<UseVector>(source, + '-', "", + '<', "&lt;", + '>', "&gt;", + '\'', "&#39;", + '\"', "&quot;", + '&', "&amp;" + ); + +#ifdef CHECK_RESULT + if (result + != + "abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;" + ) { + state.SkipWithError("not equal"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}150153301354706
+ +

Replace All Str To Longer Size

+ + + + + + + + + + + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
replace bb to ---- in std::string|64template<size_t Long> +void ReplaceAllLongerStdString(benchmark::State& state) { + std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + std::string_view sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + std::string_view pattern = "bb"; + std::string_view repl = "----"; + + std::string big_source, big_sample; + for (int i = 0; i < Long; i++) { + big_source += source; + big_sample += sample; + } + + for (auto _: state) { + std::string result{big_source}; + size_t start_pos = 0; + while((start_pos = result.find(pattern, start_pos)) != std::string::npos) { + result.replace(start_pos, pattern.length(), repl); + start_pos += repl.length(); + } +#ifdef CHECK_RESULT + if (result != big_sample) { + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}161162238245832
replace bb to ---- in std::string|256template<size_t Long> +void ReplaceAllLongerStdString(benchmark::State& state) { + std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + std::string_view sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + std::string_view pattern = "bb"; + std::string_view repl = "----"; + + std::string big_source, big_sample; + for (int i = 0; i < Long; i++) { + big_source += source; + big_sample += sample; + } + + for (auto _: state) { + std::string result{big_source}; + size_t start_pos = 0; + while((start_pos = result.find(pattern, start_pos)) != std::string::npos) { + result.replace(start_pos, pattern.length(), repl); + start_pos += repl.length(); + } +#ifdef CHECK_RESULT + if (result != big_sample) { + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}5414937798522559
replace bb to ---- in std::string|512template<size_t Long> +void ReplaceAllLongerStdString(benchmark::State& state) { + std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + std::string_view sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + std::string_view pattern = "bb"; + std::string_view repl = "----"; + + std::string big_source, big_sample; + for (int i = 0; i < Long; i++) { + big_source += source; + big_sample += sample; + } + + for (auto _: state) { + std::string result{big_source}; + size_t start_pos = 0; + while((start_pos = result.find(pattern, start_pos)) != std::string::npos) { + result.replace(start_pos, pattern.length(), repl); + start_pos += repl.length(); + } +#ifdef CHECK_RESULT + if (result != big_sample) { + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}1075993145015344466
replace bb to ---- in std::string|1024template<size_t Long> +void ReplaceAllLongerStdString(benchmark::State& state) { + std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + std::string_view sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + std::string_view pattern = "bb"; + std::string_view repl = "----"; + + std::string big_source, big_sample; + for (int i = 0; i < Long; i++) { + big_source += source; + big_sample += sample; + } + + for (auto _: state) { + std::string result{big_source}; + size_t start_pos = 0; + while((start_pos = result.find(pattern, start_pos)) != std::string::npos) { + result.replace(start_pos, pattern.length(), repl); + start_pos += repl.length(); + } +#ifdef CHECK_RESULT + if (result != big_sample) { + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}23442333324633818916
replace bb to ---- in std::string|2048template<size_t Long> +void ReplaceAllLongerStdString(benchmark::State& state) { + std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + std::string_view sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + std::string_view pattern = "bb"; + std::string_view repl = "----"; + + std::string big_source, big_sample; + for (int i = 0; i < Long; i++) { + big_source += source; + big_sample += sample; + } + + for (auto _: state) { + std::string result{big_source}; + size_t start_pos = 0; + while((start_pos = result.find(pattern, start_pos)) != std::string::npos) { + result.replace(start_pos, pattern.length(), repl); + start_pos += repl.length(); + } +#ifdef CHECK_RESULT + if (result != big_sample) { + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}636663598153808119324
replace bb to ---- in lstringa<8>|64template<size_t N, size_t Count> +void ReplaceAllLongerSimString(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + lstringa<N> result = big_source; + result.replace("bb", "----"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}145167343349749
replace bb to ---- in lstringa<8>|256template<size_t N, size_t Count> +void ReplaceAllLongerSimString(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + lstringa<N> result = big_source; + result.replace("bb", "----"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}4384956457022053
replace bb to ---- in lstringa<8>|512template<size_t N, size_t Count> +void ReplaceAllLongerSimString(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + lstringa<N> result = big_source; + result.replace("bb", "----"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}824922108011873754
replace bb to ---- in lstringa<8>|1024template<size_t N, size_t Count> +void ReplaceAllLongerSimString(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + lstringa<N> result = big_source; + result.replace("bb", "----"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}16621862191620876775
replace bb to ---- in lstringa<8>|2048template<size_t N, size_t Count> +void ReplaceAllLongerSimString(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + lstringa<N> result = big_source; + result.replace("bb", "----"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}310835513650403913478
replace bb to ---- by init stringa|64template<size_t Count> +void ReplaceAllLongerSimStringExpr(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + stringa result = e_repl(big_source.to_str(), "bb", "----"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}116121216230503
replace bb to ---- by init stringa|256template<size_t Count> +void ReplaceAllLongerSimStringExpr(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + stringa result = e_repl(big_source.to_str(), "bb", "----"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}3894445485731848
replace bb to ---- by init stringa|512template<size_t Count> +void ReplaceAllLongerSimStringExpr(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + stringa result = e_repl(big_source.to_str(), "bb", "----"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}79782794110093537
replace bb to ---- by init stringa|1024template<size_t Count> +void ReplaceAllLongerSimStringExpr(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + stringa result = e_repl(big_source.to_str(), "bb", "----"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}16291637177519886923
replace bb to ---- by init stringa|2048template<size_t Count> +void ReplaceAllLongerSimStringExpr(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + stringa result = e_repl(big_source.to_str(), "bb", "----"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}312532803478379013739
+ +

Replace All Str To Same Size

+ + + + + + + + + + + + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
replace bb to -- in std::string|64template<size_t Long> +void ReplaceAllEqualStdString(benchmark::State& state) { + std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + std::string_view sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + std::string_view pattern = "bb"; + std::string_view repl = "--"; + + std::string big_source, big_sample; + for (int i = 0; i < Long; i++) { + big_source += source; + big_sample += sample; + } + + for (auto _: state) { + std::string result{big_source}; + size_t start_pos = 0; + while((start_pos = result.find(pattern, start_pos)) != std::string::npos) { + result.replace(start_pos, pattern.length(), repl); + start_pos += repl.length(); + } +#ifdef CHECK_RESULT + if (result != big_sample) { + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}129125196218570
replace bb to -- in std::string|256template<size_t Long> +void ReplaceAllEqualStdString(benchmark::State& state) { + std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + std::string_view sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + std::string_view pattern = "bb"; + std::string_view repl = "--"; + + std::string big_source, big_sample; + for (int i = 0; i < Long; i++) { + big_source += source; + big_sample += sample; + } + + for (auto _: state) { + std::string result{big_source}; + size_t start_pos = 0; + while((start_pos = result.find(pattern, start_pos)) != std::string::npos) { + result.replace(start_pos, pattern.length(), repl); + start_pos += repl.length(); + } +#ifdef CHECK_RESULT + if (result != big_sample) { + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}4044055035391885
replace bb to -- in std::string|512template<size_t Long> +void ReplaceAllEqualStdString(benchmark::State& state) { + std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + std::string_view sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + std::string_view pattern = "bb"; + std::string_view repl = "--"; + + std::string big_source, big_sample; + for (int i = 0; i < Long; i++) { + big_source += source; + big_sample += sample; + } + + for (auto _: state) { + std::string result{big_source}; + size_t start_pos = 0; + while((start_pos = result.find(pattern, start_pos)) != std::string::npos) { + result.replace(start_pos, pattern.length(), repl); + start_pos += repl.length(); + } +#ifdef CHECK_RESULT + if (result != big_sample) { + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}8157808649793523
replace bb to -- in std::string|1024template<size_t Long> +void ReplaceAllEqualStdString(benchmark::State& state) { + std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + std::string_view sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + std::string_view pattern = "bb"; + std::string_view repl = "--"; + + std::string big_source, big_sample; + for (int i = 0; i < Long; i++) { + big_source += source; + big_sample += sample; + } + + for (auto _: state) { + std::string result{big_source}; + size_t start_pos = 0; + while((start_pos = result.find(pattern, start_pos)) != std::string::npos) { + result.replace(start_pos, pattern.length(), repl); + start_pos += repl.length(); + } +#ifdef CHECK_RESULT + if (result != big_sample) { + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}14891446170018856916
replace bb to -- in std::string|2048template<size_t Long> +void ReplaceAllEqualStdString(benchmark::State& state) { + std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + std::string_view sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + std::string_view pattern = "bb"; + std::string_view repl = "--"; + + std::string big_source, big_sample; + for (int i = 0; i < Long; i++) { + big_source += source; + big_sample += sample; + } + + for (auto _: state) { + std::string result{big_source}; + size_t start_pos = 0; + while((start_pos = result.find(pattern, start_pos)) != std::string::npos) { + result.replace(start_pos, pattern.length(), repl); + start_pos += repl.length(); + } +#ifdef CHECK_RESULT + if (result != big_sample) { + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}310031383239357613510
replace bb to -- in lstringa<8>|64template<size_t N, size_t Long> +void ReplaceAllEqualSimString(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + lstringa<2048> big_source{Long, source}, big_sample{Long, sample}; + + for (auto _: state) { + lstringa<N> result = big_source; + result.replace("bb", "--"); + + #ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}101103192202482
replace bb to -- in lstringa<8>|256template<size_t N, size_t Long> +void ReplaceAllEqualSimString(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + lstringa<2048> big_source{Long, source}, big_sample{Long, sample}; + + for (auto _: state) { + lstringa<N> result = big_source; + result.replace("bb", "--"); + + #ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}3023014524701565
replace bb to -- in lstringa<8>|512template<size_t N, size_t Long> +void ReplaceAllEqualSimString(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + lstringa<2048> big_source{Long, source}, big_sample{Long, sample}; + + for (auto _: state) { + lstringa<N> result = big_source; + result.replace("bb", "--"); + + #ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}5795487978162921
replace bb to -- in lstringa<8>|1024template<size_t N, size_t Long> +void ReplaceAllEqualSimString(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + lstringa<2048> big_source{Long, source}, big_sample{Long, sample}; + + for (auto _: state) { + lstringa<N> result = big_source; + result.replace("bb", "--"); + + #ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}11811112144415155594
replace bb to -- in lstringa<8>|2048template<size_t N, size_t Long> +void ReplaceAllEqualSimString(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + lstringa<2048> big_source{Long, source}, big_sample{Long, sample}; + + for (auto _: state) { + lstringa<N> result = big_source; + result.replace("bb", "--"); + + #ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + } +}218121052839290910928
replace bb to -- by init stringa|64template<size_t Count> +void ReplaceAllEqualSimStringExpr(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + ssa pattern = "bb"; + ssa repl = "--"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + stringa result = e_repl(big_source.to_str(), "bb", "--"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}82.991.4167183366
replace bb to -- by init stringa|256template<size_t Count> +void ReplaceAllEqualSimStringExpr(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + ssa pattern = "bb"; + ssa repl = "--"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + stringa result = e_repl(big_source.to_str(), "bb", "--"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}2192613523921224
replace bb to -- by init stringa|512template<size_t Count> +void ReplaceAllEqualSimStringExpr(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + ssa pattern = "bb"; + ssa repl = "--"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + stringa result = e_repl(big_source.to_str(), "bb", "--"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}4474855986682221
replace bb to -- by init stringa|1024template<size_t Count> +void ReplaceAllEqualSimStringExpr(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + ssa pattern = "bb"; + ssa repl = "--"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + stringa result = e_repl(big_source.to_str(), "bb", "--"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}880984108212014235
replace bb to -- by init stringa|2048template<size_t Count> +void ReplaceAllEqualSimStringExpr(benchmark::State& state) { + ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba"; + ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a"; + ssa pattern = "bb"; + ssa repl = "--"; + + lstringa<2048> big_source{Count, source}, big_sample{Count, sample}; + + for (auto _: state) { + stringa result = e_repl(big_source.to_str(), "bb", "--"); + +#ifdef CHECK_RESULT + if (result.to_str() != big_sample) { + std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n"; + state.SkipWithError("error in replace"); + break; + } +#endif + benchmark::DoNotOptimize(result); + benchmark::DoNotOptimize(source); + benchmark::DoNotOptimize(pattern); + benchmark::DoNotOptimize(repl); + } +}16541862196322958496
+ +

Hash Map insert and find

+ + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
hashStrMapA<size_t> emplace & find stringa;void HashMapSimStr(benchmark::State& state) { + for (auto _: state) { + hashStrMapA<size_t> store; + for (size_t idx = 0; idx < bs_sim.size(); idx++) { + store.try_emplace(bs_sim[idx], idx); + } +#ifdef CHECK_RESULT + if (store.size() != bs_sim.size()) { + state.SkipWithError("bad inserts"); + } +#endif + for (size_t idx = 0; idx < bs_sim.size(); idx++) { + auto find = store.find(bs_sim[idx]); + size_t res = find->second; +#ifdef CHECK_RESULT + if (res != idx) { + state.SkipWithError("bad find"); + } +#endif + benchmark::DoNotOptimize(res); + } + } +} >> Вставляем в hashStrMapA 10000 stringa длиной от 30 до 50 +символов, а потом ищем их в ней37189003769704414490042373355327536
std::unordered_map<std::string, size_t> emplace & find std::string;void HashMapStdStr(benchmark::State& state) { + for (auto _: state) { + std::unordered_map<std::string, size_t> store; + for (size_t idx = 0; idx < bs_std.size(); idx++) { + store.try_emplace(bs_std[idx], idx); + } +#ifdef CHECK_RESULT + if (store.size() != bs_std.size()) { + state.SkipWithError("bad inserts"); + } +#endif + for (size_t idx = 0; idx < bs_std.size(); idx++) { + auto find = store.find(bs_std[idx]); + size_t res = find->second; +#ifdef CHECK_RESULT + if (res != idx) { + state.SkipWithError("bad find"); + } +#endif + benchmark::DoNotOptimize(res); + } + } +} >> То же самое c std::string и std::unordered_map36914423652417598496254680196172235
hashStrMapA<size_t> emplace & find ssa;void HashMapSimSsa(benchmark::State& state) { + for (auto _: state) { + hashStrMapA<size_t> store; + for (size_t idx = 0; idx < bs_sim.size(); idx++) { + store.emplace(bs_sim[idx], idx); + } +#ifdef CHECK_RESULT + if (store.size() != bs_sim.size()) { + state.SkipWithError("bad inserts"); + } +#endif + for (size_t idx = 0; idx < bs_sim.size(); idx++) { + ssa key = bs_sim[idx]; + auto find = store.find(key); + size_t res = find->second; +#ifdef CHECK_RESULT + if (res != idx) { + state.SkipWithError("bad find"); + } +#endif + benchmark::DoNotOptimize(res); + } + } +} >> Теперь вставляем stringa, а ищем ssa37198443800957398370839909215318092
std::unordered_map<std::string, size_t> emplace & find std::string_view;void HashMapStdStrView(benchmark::State& state) { + for (auto _: state) { + std::unordered_map<std::string, size_t> store; + for (size_t idx = 0; idx < bs_std.size(); idx++) { + store.emplace(bs_std[idx], idx); + } +#ifdef CHECK_RESULT + if (store.size() != bs_std.size()) { + state.SkipWithError("bad inserts"); + } +#endif + for (size_t idx = 0; idx < bs_std.size(); idx++) { + std::string_view key = bs_std[idx]; + auto find = store.find(std::string{key}); + size_t res = find->second; +#ifdef CHECK_RESULT + if (res != idx) { + state.SkipWithError("bad find"); + } +#endif + benchmark::DoNotOptimize(res); + } + } +} >> Вставляем std::string, а ищем std::string_view41157864103196703027663046517002408
+ +

Build Full Func Name

+ + + + + + +
Benchmark nameCommentXeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13Xeon E5-2682 v4, Windows 10, Clang-19Xeon E5-2682 v4, Windows 10, MSVC-19Xeon E5-2682 v4, WASM Chrome, Clang-21
Build func full name std::string;std::string build_full_name_std() const { + std::string str{has_ret_type_resolver ? "any"sv : type_names_sv[(unsigned)ret_type]}; + str += " "; + str += std_name; + str += "("; + + bool add_comma = false; + + for (const auto& param : params) { + if (add_comma) { + str += ", "; + } + if (param.optional) { + str += "["; + } + param.allowed_types.to_stdstr(str); + if (param.optional) { + str += "]"; + } + add_comma = true; + } + if (unlim_params) { + if (add_comma) { + str += ", "; + } + str += "..."; + } + str += ")"; + //std::cout << "Len=" << str.length() << ", Cap=" << str.capacity() << "\n"; + return str; +} >> Обыденная задача, подобные часто могут встретится в работе: +По неким данным сгенерировать текст. В этом случае по данным +о неких функциях сформировать их полное имя с типами параметров и +возвращаемого значения. Алгоритм на std::string.733949158816605576
Build func full name std::string 1;std::string build_full_name_std1() const { + std::string str{has_ret_type_resolver ? "any"sv : type_names_sv[(unsigned)ret_type]}; + str += " " + std_name + "("; + + bool add_comma = false; + + for (const auto& param : params) { + if (add_comma) { + str += ", "; + } + if (param.optional) { + str += "["; + } + param.allowed_types.to_stdstr(str); + if (param.optional) { + str += "]"; + } + add_comma = true; + } + if (unlim_params) { + if (add_comma) { + str += ", "; + } + str += "..."; + } + str += ")"; + //std::cout << "Len=" << str.length() << ", Cap=" << str.capacity() << "\n"; + return str; +} >> Почти тот же алгоритм, но несколько последовательных ++= к строке заменены на одно += + + +.8371025164817475877
Build func full name std::stream;std::string build_full_name_stream() const { + std::ostringstream str; + if (has_ret_type_resolver) { + str << "any"; + } else { + str << type_names_sv[(unsigned)ret_type]; + } + str << " " << std_name << "("; + + bool add_comma = false; + + for (const auto& param : params) { + if (add_comma) { + str << ", "; + } + if (param.optional) { + str << "["; + } + param.allowed_types.to_stream(str); + if (param.optional) { + str << "]"; + } + add_comma = true; + } + if (unlim_params) { + if (add_comma) { + str << ", "; + } + str << "..."; + } + str << ")"; + return str.str(); +} >> Строим имя функции через std::ostringstream и <<2608265410979994216604
Build func full name stringa;stringa build_full_name() const { + lstringa<512> str = e_choice(has_ret_type_resolver, "any", type_names[(unsigned)ret_type]) + " " + name + "("; + + bool add_comma = false; + + for (const auto& param : params) { + str += e_if(add_comma, ", ") + e_if(param.optional, "["); + param.allowed_types.to_simstr(str); + if (param.optional) { + str += "]"; + } + add_comma = true; + } + return str + e_if(unlim_params, e_if(add_comma, ", ") + "...") + ")"; +} >> Реализация на simstr строках и строковых выражениях. +Инфа о параметрах добавляется в текущую строку5125008478912780
Build func full name stringa 1;stringa build_full_name1() const { + lstringa<512> str = e_choice(has_ret_type_resolver, "any", type_names[(unsigned)ret_type]) + " " + name + "("; + + bool add_comma = false; + + for (const auto& param : params) { + str += e_if(add_comma, ", ") + e_if(param.optional, "[") + param.allowed_types.get_simstr() + e_if(param.optional, "]"); + add_comma = true; + } + return str + e_if(unlim_params, e_if(add_comma, ", ") + "...") + ")"; +} >> Реализация на simstr строках и строковых выражениях. +Инфа о параметрах добавляется во временную строку, а потом +разом добавляется в текущую строку. Позволяет операции в цикле +записать в одну строку, но чуть проигрывает по времени выполнения.657716100310073249
diff --git a/bench/results/000-Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21.txt b/bench/results/000-Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21.txt new file mode 100644 index 0000000..02c102d --- /dev/null +++ b/bench/results/000-Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21.txt @@ -0,0 +1,778 @@ +2025-08-06T14:11:08+03:00 +Running ./benchStr +Run on (32 X 2494.22 MHz CPU s) +CPU Caches: + L1 Data 32 KiB (x16) + L1 Instruction 32 KiB (x16) + L2 Unified 256 KiB (x16) + L3 Unified 40960 KiB (x1) +Load Average: 0.49, 0.86, 0.76 +-------------------------------------------------------------------------------------------------------------------------------------------------------- +Benchmark Time CPU Iterations +-------------------------------------------------------------------------------------------------------------------------------------------------------- +----- Create Empty Str ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e;_mean 1.13 ns 1.13 ns 10 +std::string e;_median 1.13 ns 1.13 ns 10 +std::string e;_stddev 0.014 ns 0.014 ns 10 +std::string e;_cv 1.23 % 1.23 % 10 +std::string_view e;_mean 0.372 ns 0.372 ns 10 +std::string_view e;_median 0.373 ns 0.373 ns 10 +std::string_view e;_stddev 0.007 ns 0.007 ns 10 +std::string_view e;_cv 1.77 % 1.77 % 10 +ssa e;_mean 0.375 ns 0.375 ns 10 +ssa e;_median 0.372 ns 0.372 ns 10 +ssa e;_stddev 0.012 ns 0.012 ns 10 +ssa e;_cv 3.21 % 3.21 % 10 +stringa e;_mean 0.757 ns 0.757 ns 10 +stringa e;_median 0.753 ns 0.753 ns 10 +stringa e;_stddev 0.011 ns 0.011 ns 10 +stringa e;_cv 1.45 % 1.45 % 10 +lstringa<20> e;_mean 1.16 ns 1.16 ns 10 +lstringa<20> e;_median 1.16 ns 1.16 ns 10 +lstringa<20> e;_stddev 0.029 ns 0.029 ns 10 +lstringa<20> e;_cv 2.46 % 2.46 % 10 +lstringa<40> e;_mean 1.14 ns 1.14 ns 10 +lstringa<40> e;_median 1.14 ns 1.14 ns 10 +lstringa<40> e;_stddev 0.013 ns 0.013 ns 10 +lstringa<40> e;_cv 1.14 % 1.14 % 10 +----- Create Str from short literal (9 symbols) --------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "Test text";_mean 1.88 ns 1.88 ns 10 +std::string e = "Test text";_median 1.88 ns 1.88 ns 10 +std::string e = "Test text";_stddev 0.017 ns 0.017 ns 10 +std::string e = "Test text";_cv 0.91 % 0.91 % 10 +std::string_view e = "Test text";_mean 0.746 ns 0.746 ns 10 +std::string_view e = "Test text";_median 0.748 ns 0.748 ns 10 +std::string_view e = "Test text";_stddev 0.008 ns 0.008 ns 10 +std::string_view e = "Test text";_cv 1.04 % 1.04 % 10 +ssa e = "Test text";_mean 0.377 ns 0.377 ns 10 +ssa e = "Test text";_median 0.373 ns 0.373 ns 10 +ssa e = "Test text";_stddev 0.017 ns 0.017 ns 10 +ssa e = "Test text";_cv 4.49 % 4.49 % 10 +stringa e = "Test text";_mean 1.12 ns 1.12 ns 10 +stringa e = "Test text";_median 1.12 ns 1.12 ns 10 +stringa e = "Test text";_stddev 0.016 ns 0.016 ns 10 +stringa e = "Test text";_cv 1.42 % 1.42 % 10 +lstringa<20> e = "Test text";_mean 1.89 ns 1.89 ns 10 +lstringa<20> e = "Test text";_median 1.90 ns 1.90 ns 10 +lstringa<20> e = "Test text";_stddev 0.030 ns 0.030 ns 10 +lstringa<20> e = "Test text";_cv 1.61 % 1.61 % 10 +lstringa<40> e = "Test text";_mean 1.90 ns 1.90 ns 10 +lstringa<40> e = "Test text";_median 1.90 ns 1.90 ns 10 +lstringa<40> e = "Test text";_stddev 0.024 ns 0.024 ns 10 +lstringa<40> e = "Test text";_cv 1.27 % 1.27 % 10 +----- Create Str from long literal (30 symbols) ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "123456789012345678901234567890";_mean 19.5 ns 19.5 ns 10 +std::string e = "123456789012345678901234567890";_median 19.5 ns 19.5 ns 10 +std::string e = "123456789012345678901234567890";_stddev 0.423 ns 0.423 ns 10 +std::string e = "123456789012345678901234567890";_cv 2.17 % 2.17 % 10 +std::string_view e = "123456789012345678901234567890";_mean 0.758 ns 0.758 ns 10 +std::string_view e = "123456789012345678901234567890";_median 0.761 ns 0.761 ns 10 +std::string_view e = "123456789012345678901234567890";_stddev 0.012 ns 0.012 ns 10 +std::string_view e = "123456789012345678901234567890";_cv 1.56 % 1.56 % 10 +ssa e = "123456789012345678901234567890";_mean 0.376 ns 0.376 ns 10 +ssa e = "123456789012345678901234567890";_median 0.375 ns 0.375 ns 10 +ssa e = "123456789012345678901234567890";_stddev 0.009 ns 0.009 ns 10 +ssa e = "123456789012345678901234567890";_cv 2.36 % 2.36 % 10 +stringa e = "123456789012345678901234567890";_mean 1.13 ns 1.13 ns 10 +stringa e = "123456789012345678901234567890";_median 1.13 ns 1.13 ns 10 +stringa e = "123456789012345678901234567890";_stddev 0.015 ns 0.015 ns 10 +stringa e = "123456789012345678901234567890";_cv 1.32 % 1.32 % 10 +lstringa<20> e = "123456789012345678901234567890";_mean 20.5 ns 20.5 ns 10 +lstringa<20> e = "123456789012345678901234567890";_median 20.6 ns 20.6 ns 10 +lstringa<20> e = "123456789012345678901234567890";_stddev 0.419 ns 0.419 ns 10 +lstringa<20> e = "123456789012345678901234567890";_cv 2.05 % 2.05 % 10 +lstringa<40> e = "123456789012345678901234567890";_mean 1.90 ns 1.90 ns 10 +lstringa<40> e = "123456789012345678901234567890";_median 1.90 ns 1.90 ns 10 +lstringa<40> e = "123456789012345678901234567890";_stddev 0.020 ns 0.020 ns 10 +lstringa<40> e = "123456789012345678901234567890";_cv 1.06 % 1.06 % 10 +----- Create copy of Str with 9 symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "Test text"; auto c{e};_mean 5.73 ns 5.73 ns 10 +std::string e = "Test text"; auto c{e};_median 5.73 ns 5.73 ns 10 +std::string e = "Test text"; auto c{e};_stddev 0.039 ns 0.039 ns 10 +std::string e = "Test text"; auto c{e};_cv 0.69 % 0.69 % 10 +std::string_view e = "Test text"; auto c{e};_mean 0.381 ns 0.381 ns 10 +std::string_view e = "Test text"; auto c{e};_median 0.383 ns 0.383 ns 10 +std::string_view e = "Test text"; auto c{e};_stddev 0.011 ns 0.011 ns 10 +std::string_view e = "Test text"; auto c{e};_cv 2.78 % 2.78 % 10 +ssa e = "Test text"; auto c{e};_mean 0.376 ns 0.376 ns 10 +ssa e = "Test text"; auto c{e};_median 0.376 ns 0.376 ns 10 +ssa e = "Test text"; auto c{e};_stddev 0.005 ns 0.005 ns 10 +ssa e = "Test text"; auto c{e};_cv 1.44 % 1.44 % 10 +stringa e = "Test text"; auto c{e};_mean 1.12 ns 1.12 ns 10 +stringa e = "Test text"; auto c{e};_median 1.12 ns 1.12 ns 10 +stringa e = "Test text"; auto c{e};_stddev 0.018 ns 0.018 ns 10 +stringa e = "Test text"; auto c{e};_cv 1.57 % 1.57 % 10 +lstringa<20> e = "Test text"; auto c{e};_mean 5.00 ns 5.00 ns 10 +lstringa<20> e = "Test text"; auto c{e};_median 4.97 ns 4.97 ns 10 +lstringa<20> e = "Test text"; auto c{e};_stddev 0.196 ns 0.196 ns 10 +lstringa<20> e = "Test text"; auto c{e};_cv 3.92 % 3.92 % 10 +lstringa<40> e = "Test text"; auto c{e};_mean 4.62 ns 4.62 ns 10 +lstringa<40> e = "Test text"; auto c{e};_median 4.60 ns 4.60 ns 10 +lstringa<40> e = "Test text"; auto c{e};_stddev 0.087 ns 0.087 ns 10 +lstringa<40> e = "Test text"; auto c{e};_cv 1.88 % 1.88 % 10 +----- Create copy of Str with 30 symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "123456789012345678901234567890"; auto c{e};_mean 19.8 ns 19.8 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_median 19.7 ns 19.7 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_stddev 0.324 ns 0.324 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_cv 1.64 % 1.64 % 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_mean 0.763 ns 0.763 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_median 0.762 ns 0.762 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_stddev 0.010 ns 0.010 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_cv 1.34 % 1.34 % 10 +ssa e = "123456789012345678901234567890"; auto c{e};_mean 0.373 ns 0.373 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_median 0.374 ns 0.374 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_stddev 0.005 ns 0.005 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_cv 1.34 % 1.34 % 10 +stringa e = "123456789012345678901234567890"; auto c{e};_mean 1.14 ns 1.14 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_median 1.13 ns 1.13 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_stddev 0.032 ns 0.032 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_cv 2.85 % 2.85 % 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_mean 20.2 ns 20.2 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_median 20.2 ns 20.2 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_stddev 0.221 ns 0.221 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_cv 1.10 % 1.10 % 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_mean 4.68 ns 4.68 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_median 4.61 ns 4.61 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_stddev 0.202 ns 0.202 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_cv 4.32 % 4.32 % 10 +----- Find 9 symbols text in end of 99 symbols text ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string::find;_mean 7.73 ns 7.73 ns 10 +std::string::find;_median 7.71 ns 7.71 ns 10 +std::string::find;_stddev 0.128 ns 0.128 ns 10 +std::string::find;_cv 1.66 % 1.66 % 10 +std::string_view::find;_mean 7.25 ns 7.25 ns 10 +std::string_view::find;_median 7.28 ns 7.28 ns 10 +std::string_view::find;_stddev 0.083 ns 0.083 ns 10 +std::string_view::find;_cv 1.15 % 1.15 % 10 +ssa::find;_mean 6.91 ns 6.91 ns 10 +ssa::find;_median 6.93 ns 6.93 ns 10 +ssa::find;_stddev 0.115 ns 0.115 ns 10 +ssa::find;_cv 1.66 % 1.66 % 10 +stringa::find;_mean 8.10 ns 8.10 ns 10 +stringa::find;_median 8.07 ns 8.08 ns 10 +stringa::find;_stddev 0.122 ns 0.122 ns 10 +stringa::find;_cv 1.51 % 1.51 % 10 +lstringa<20>::find;_mean 6.91 ns 6.91 ns 10 +lstringa<20>::find;_median 6.91 ns 6.91 ns 10 +lstringa<20>::find;_stddev 0.154 ns 0.154 ns 10 +lstringa<20>::find;_cv 2.23 % 2.23 % 10 +lstringa<40>::find;_mean 6.92 ns 6.92 ns 10 +lstringa<40>::find;_median 6.93 ns 6.93 ns 10 +lstringa<40>::find;_stddev 0.172 ns 0.172 ns 10 +lstringa<40>::find;_cv 2.49 % 2.49 % 10 +------- Copy not literal Str with N symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string copy{str_with_len_N};/15_mean 5.87 ns 5.87 ns 10 +std::string copy{str_with_len_N};/15_median 5.87 ns 5.87 ns 10 +std::string copy{str_with_len_N};/15_stddev 0.085 ns 0.085 ns 10 +std::string copy{str_with_len_N};/15_cv 1.44 % 1.44 % 10 +std::string copy{str_with_len_N};/16_mean 23.5 ns 23.5 ns 10 +std::string copy{str_with_len_N};/16_median 23.4 ns 23.4 ns 10 +std::string copy{str_with_len_N};/16_stddev 0.447 ns 0.447 ns 10 +std::string copy{str_with_len_N};/16_cv 1.91 % 1.91 % 10 +std::string copy{str_with_len_N};/23_mean 23.6 ns 23.6 ns 10 +std::string copy{str_with_len_N};/23_median 23.4 ns 23.4 ns 10 +std::string copy{str_with_len_N};/23_stddev 0.709 ns 0.709 ns 10 +std::string copy{str_with_len_N};/23_cv 3.00 % 3.00 % 10 +std::string copy{str_with_len_N};/24_mean 23.7 ns 23.7 ns 10 +std::string copy{str_with_len_N};/24_median 23.3 ns 23.3 ns 10 +std::string copy{str_with_len_N};/24_stddev 1.24 ns 1.24 ns 10 +std::string copy{str_with_len_N};/24_cv 5.26 % 5.26 % 10 +std::string copy{str_with_len_N};/32_mean 23.1 ns 23.1 ns 10 +std::string copy{str_with_len_N};/32_median 23.3 ns 23.3 ns 10 +std::string copy{str_with_len_N};/32_stddev 0.601 ns 0.601 ns 10 +std::string copy{str_with_len_N};/32_cv 2.60 % 2.60 % 10 +std::string copy{str_with_len_N};/64_mean 23.1 ns 23.1 ns 10 +std::string copy{str_with_len_N};/64_median 23.1 ns 23.1 ns 10 +std::string copy{str_with_len_N};/64_stddev 0.397 ns 0.397 ns 10 +std::string copy{str_with_len_N};/64_cv 1.72 % 1.72 % 10 +std::string copy{str_with_len_N};/128_mean 25.4 ns 25.4 ns 10 +std::string copy{str_with_len_N};/128_median 25.2 ns 25.2 ns 10 +std::string copy{str_with_len_N};/128_stddev 0.566 ns 0.566 ns 10 +std::string copy{str_with_len_N};/128_cv 2.23 % 2.23 % 10 +std::string copy{str_with_len_N};/256_mean 25.5 ns 25.5 ns 10 +std::string copy{str_with_len_N};/256_median 25.5 ns 25.5 ns 10 +std::string copy{str_with_len_N};/256_stddev 0.397 ns 0.397 ns 10 +std::string copy{str_with_len_N};/256_cv 1.55 % 1.55 % 10 +std::string copy{str_with_len_N};/512_mean 30.4 ns 30.4 ns 10 +std::string copy{str_with_len_N};/512_median 30.2 ns 30.2 ns 10 +std::string copy{str_with_len_N};/512_stddev 0.955 ns 0.955 ns 10 +std::string copy{str_with_len_N};/512_cv 3.14 % 3.14 % 10 +std::string copy{str_with_len_N};/1024_mean 39.0 ns 39.0 ns 10 +std::string copy{str_with_len_N};/1024_median 39.0 ns 39.0 ns 10 +std::string copy{str_with_len_N};/1024_stddev 0.363 ns 0.363 ns 10 +std::string copy{str_with_len_N};/1024_cv 0.93 % 0.93 % 10 +std::string copy{str_with_len_N};/2048_mean 111 ns 111 ns 10 +std::string copy{str_with_len_N};/2048_median 110 ns 110 ns 10 +std::string copy{str_with_len_N};/2048_stddev 5.75 ns 5.75 ns 10 +std::string copy{str_with_len_N};/2048_cv 5.17 % 5.17 % 10 +std::string copy{str_with_len_N};/4096_mean 142 ns 142 ns 10 +std::string copy{str_with_len_N};/4096_median 144 ns 144 ns 10 +std::string copy{str_with_len_N};/4096_stddev 7.30 ns 7.30 ns 10 +std::string copy{str_with_len_N};/4096_cv 5.14 % 5.14 % 10 +stringa copy{str_with_len_N};/15_mean 1.13 ns 1.13 ns 10 +stringa copy{str_with_len_N};/15_median 1.12 ns 1.12 ns 10 +stringa copy{str_with_len_N};/15_stddev 0.046 ns 0.046 ns 10 +stringa copy{str_with_len_N};/15_cv 4.10 % 4.10 % 10 +stringa copy{str_with_len_N};/16_mean 1.12 ns 1.12 ns 10 +stringa copy{str_with_len_N};/16_median 1.12 ns 1.12 ns 10 +stringa copy{str_with_len_N};/16_stddev 0.023 ns 0.023 ns 10 +stringa copy{str_with_len_N};/16_cv 2.04 % 2.04 % 10 +stringa copy{str_with_len_N};/23_mean 1.12 ns 1.12 ns 10 +stringa copy{str_with_len_N};/23_median 1.11 ns 1.11 ns 10 +stringa copy{str_with_len_N};/23_stddev 0.012 ns 0.012 ns 10 +stringa copy{str_with_len_N};/23_cv 1.08 % 1.08 % 10 +stringa copy{str_with_len_N};/24_mean 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/24_median 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/24_stddev 0.071 ns 0.071 ns 10 +stringa copy{str_with_len_N};/24_cv 0.43 % 0.43 % 10 +stringa copy{str_with_len_N};/32_mean 16.4 ns 16.4 ns 10 +stringa copy{str_with_len_N};/32_median 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/32_stddev 0.212 ns 0.212 ns 10 +stringa copy{str_with_len_N};/32_cv 1.29 % 1.29 % 10 +stringa copy{str_with_len_N};/64_mean 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/64_median 16.2 ns 16.2 ns 10 +stringa copy{str_with_len_N};/64_stddev 0.086 ns 0.086 ns 10 +stringa copy{str_with_len_N};/64_cv 0.53 % 0.53 % 10 +stringa copy{str_with_len_N};/128_mean 16.6 ns 16.6 ns 10 +stringa copy{str_with_len_N};/128_median 16.6 ns 16.6 ns 10 +stringa copy{str_with_len_N};/128_stddev 0.091 ns 0.091 ns 10 +stringa copy{str_with_len_N};/128_cv 0.55 % 0.55 % 10 +stringa copy{str_with_len_N};/256_mean 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/256_median 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/256_stddev 0.105 ns 0.105 ns 10 +stringa copy{str_with_len_N};/256_cv 0.64 % 0.64 % 10 +stringa copy{str_with_len_N};/512_mean 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/512_median 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/512_stddev 0.098 ns 0.098 ns 10 +stringa copy{str_with_len_N};/512_cv 0.60 % 0.60 % 10 +stringa copy{str_with_len_N};/1024_mean 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/1024_median 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/1024_stddev 0.082 ns 0.082 ns 10 +stringa copy{str_with_len_N};/1024_cv 0.50 % 0.50 % 10 +stringa copy{str_with_len_N};/2048_mean 16.4 ns 16.4 ns 10 +stringa copy{str_with_len_N};/2048_median 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/2048_stddev 0.092 ns 0.092 ns 10 +stringa copy{str_with_len_N};/2048_cv 0.56 % 0.56 % 10 +stringa copy{str_with_len_N};/4096_mean 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/4096_median 16.2 ns 16.2 ns 10 +stringa copy{str_with_len_N};/4096_stddev 0.291 ns 0.291 ns 10 +stringa copy{str_with_len_N};/4096_cv 1.78 % 1.78 % 10 +lstringa<16> copy{str_with_len_N};/15_mean 5.11 ns 5.11 ns 10 +lstringa<16> copy{str_with_len_N};/15_median 5.11 ns 5.11 ns 10 +lstringa<16> copy{str_with_len_N};/15_stddev 0.073 ns 0.073 ns 10 +lstringa<16> copy{str_with_len_N};/15_cv 1.43 % 1.43 % 10 +lstringa<16> copy{str_with_len_N};/16_mean 5.12 ns 5.12 ns 10 +lstringa<16> copy{str_with_len_N};/16_median 5.11 ns 5.11 ns 10 +lstringa<16> copy{str_with_len_N};/16_stddev 0.074 ns 0.074 ns 10 +lstringa<16> copy{str_with_len_N};/16_cv 1.45 % 1.45 % 10 +lstringa<16> copy{str_with_len_N};/23_mean 5.20 ns 5.20 ns 10 +lstringa<16> copy{str_with_len_N};/23_median 5.19 ns 5.19 ns 10 +lstringa<16> copy{str_with_len_N};/23_stddev 0.155 ns 0.155 ns 10 +lstringa<16> copy{str_with_len_N};/23_cv 2.98 % 2.98 % 10 +lstringa<16> copy{str_with_len_N};/24_mean 24.3 ns 24.3 ns 10 +lstringa<16> copy{str_with_len_N};/24_median 23.8 ns 23.9 ns 10 +lstringa<16> copy{str_with_len_N};/24_stddev 1.58 ns 1.58 ns 10 +lstringa<16> copy{str_with_len_N};/24_cv 6.48 % 6.48 % 10 +lstringa<16> copy{str_with_len_N};/32_mean 23.9 ns 23.9 ns 10 +lstringa<16> copy{str_with_len_N};/32_median 23.7 ns 23.7 ns 10 +lstringa<16> copy{str_with_len_N};/32_stddev 0.521 ns 0.521 ns 10 +lstringa<16> copy{str_with_len_N};/32_cv 2.18 % 2.18 % 10 +lstringa<16> copy{str_with_len_N};/64_mean 25.8 ns 25.8 ns 10 +lstringa<16> copy{str_with_len_N};/64_median 25.7 ns 25.7 ns 10 +lstringa<16> copy{str_with_len_N};/64_stddev 0.580 ns 0.580 ns 10 +lstringa<16> copy{str_with_len_N};/64_cv 2.25 % 2.25 % 10 +lstringa<16> copy{str_with_len_N};/128_mean 26.3 ns 26.3 ns 10 +lstringa<16> copy{str_with_len_N};/128_median 26.1 ns 26.1 ns 10 +lstringa<16> copy{str_with_len_N};/128_stddev 0.487 ns 0.487 ns 10 +lstringa<16> copy{str_with_len_N};/128_cv 1.85 % 1.85 % 10 +lstringa<16> copy{str_with_len_N};/256_mean 27.7 ns 27.7 ns 10 +lstringa<16> copy{str_with_len_N};/256_median 27.6 ns 27.6 ns 10 +lstringa<16> copy{str_with_len_N};/256_stddev 0.382 ns 0.382 ns 10 +lstringa<16> copy{str_with_len_N};/256_cv 1.38 % 1.38 % 10 +lstringa<16> copy{str_with_len_N};/512_mean 30.6 ns 30.6 ns 10 +lstringa<16> copy{str_with_len_N};/512_median 30.6 ns 30.6 ns 10 +lstringa<16> copy{str_with_len_N};/512_stddev 0.535 ns 0.535 ns 10 +lstringa<16> copy{str_with_len_N};/512_cv 1.75 % 1.75 % 10 +lstringa<16> copy{str_with_len_N};/1024_mean 85.9 ns 85.9 ns 10 +lstringa<16> copy{str_with_len_N};/1024_median 85.5 ns 85.5 ns 10 +lstringa<16> copy{str_with_len_N};/1024_stddev 5.05 ns 5.05 ns 10 +lstringa<16> copy{str_with_len_N};/1024_cv 5.88 % 5.88 % 10 +lstringa<16> copy{str_with_len_N};/2048_mean 99.2 ns 99.2 ns 10 +lstringa<16> copy{str_with_len_N};/2048_median 95.0 ns 95.0 ns 10 +lstringa<16> copy{str_with_len_N};/2048_stddev 8.28 ns 8.28 ns 10 +lstringa<16> copy{str_with_len_N};/2048_cv 8.34 % 8.34 % 10 +lstringa<16> copy{str_with_len_N};/4096_mean 118 ns 118 ns 10 +lstringa<16> copy{str_with_len_N};/4096_median 117 ns 117 ns 10 +lstringa<16> copy{str_with_len_N};/4096_stddev 5.73 ns 5.73 ns 10 +lstringa<16> copy{str_with_len_N};/4096_cv 4.86 % 4.86 % 10 +lstringa<512> copy{str_with_len_N};/15_mean 4.96 ns 4.96 ns 10 +lstringa<512> copy{str_with_len_N};/15_median 4.97 ns 4.97 ns 10 +lstringa<512> copy{str_with_len_N};/15_stddev 0.127 ns 0.127 ns 10 +lstringa<512> copy{str_with_len_N};/15_cv 2.57 % 2.57 % 10 +lstringa<512> copy{str_with_len_N};/16_mean 4.95 ns 4.95 ns 10 +lstringa<512> copy{str_with_len_N};/16_median 4.95 ns 4.95 ns 10 +lstringa<512> copy{str_with_len_N};/16_stddev 0.037 ns 0.037 ns 10 +lstringa<512> copy{str_with_len_N};/16_cv 0.75 % 0.75 % 10 +lstringa<512> copy{str_with_len_N};/23_mean 4.91 ns 4.91 ns 10 +lstringa<512> copy{str_with_len_N};/23_median 4.87 ns 4.87 ns 10 +lstringa<512> copy{str_with_len_N};/23_stddev 0.057 ns 0.057 ns 10 +lstringa<512> copy{str_with_len_N};/23_cv 1.17 % 1.17 % 10 +lstringa<512> copy{str_with_len_N};/24_mean 4.92 ns 4.92 ns 10 +lstringa<512> copy{str_with_len_N};/24_median 4.92 ns 4.92 ns 10 +lstringa<512> copy{str_with_len_N};/24_stddev 0.070 ns 0.070 ns 10 +lstringa<512> copy{str_with_len_N};/24_cv 1.42 % 1.42 % 10 +lstringa<512> copy{str_with_len_N};/32_mean 4.61 ns 4.61 ns 10 +lstringa<512> copy{str_with_len_N};/32_median 4.60 ns 4.60 ns 10 +lstringa<512> copy{str_with_len_N};/32_stddev 0.052 ns 0.052 ns 10 +lstringa<512> copy{str_with_len_N};/32_cv 1.12 % 1.12 % 10 +lstringa<512> copy{str_with_len_N};/64_mean 6.14 ns 6.14 ns 10 +lstringa<512> copy{str_with_len_N};/64_median 6.12 ns 6.12 ns 10 +lstringa<512> copy{str_with_len_N};/64_stddev 0.137 ns 0.137 ns 10 +lstringa<512> copy{str_with_len_N};/64_cv 2.23 % 2.23 % 10 +lstringa<512> copy{str_with_len_N};/128_mean 6.50 ns 6.50 ns 10 +lstringa<512> copy{str_with_len_N};/128_median 6.48 ns 6.48 ns 10 +lstringa<512> copy{str_with_len_N};/128_stddev 0.131 ns 0.131 ns 10 +lstringa<512> copy{str_with_len_N};/128_cv 2.02 % 2.02 % 10 +lstringa<512> copy{str_with_len_N};/256_mean 8.19 ns 8.19 ns 10 +lstringa<512> copy{str_with_len_N};/256_median 8.09 ns 8.09 ns 10 +lstringa<512> copy{str_with_len_N};/256_stddev 0.353 ns 0.353 ns 10 +lstringa<512> copy{str_with_len_N};/256_cv 4.30 % 4.30 % 10 +lstringa<512> copy{str_with_len_N};/512_mean 10.4 ns 10.4 ns 10 +lstringa<512> copy{str_with_len_N};/512_median 10.5 ns 10.5 ns 10 +lstringa<512> copy{str_with_len_N};/512_stddev 0.320 ns 0.320 ns 10 +lstringa<512> copy{str_with_len_N};/512_cv 3.07 % 3.07 % 10 +lstringa<512> copy{str_with_len_N};/1024_mean 87.0 ns 87.0 ns 10 +lstringa<512> copy{str_with_len_N};/1024_median 87.7 ns 87.7 ns 10 +lstringa<512> copy{str_with_len_N};/1024_stddev 4.05 ns 4.05 ns 10 +lstringa<512> copy{str_with_len_N};/1024_cv 4.65 % 4.65 % 10 +lstringa<512> copy{str_with_len_N};/2048_mean 103 ns 103 ns 10 +lstringa<512> copy{str_with_len_N};/2048_median 104 ns 104 ns 10 +lstringa<512> copy{str_with_len_N};/2048_stddev 7.85 ns 7.85 ns 10 +lstringa<512> copy{str_with_len_N};/2048_cv 7.64 % 7.64 % 10 +lstringa<512> copy{str_with_len_N};/4096_mean 118 ns 118 ns 10 +lstringa<512> copy{str_with_len_N};/4096_median 118 ns 118 ns 10 +lstringa<512> copy{str_with_len_N};/4096_stddev 2.48 ns 2.48 ns 10 +lstringa<512> copy{str_with_len_N};/4096_cv 2.10 % 2.10 % 10 +----- Convert to int '1234567' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_mean 27.5 ns 27.5 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_median 27.5 ns 27.5 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_stddev 0.506 ns 0.506 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_cv 1.84 % 1.84 % 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_mean 15.2 ns 15.2 ns 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_median 15.2 ns 15.2 ns 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_stddev 0.228 ns 0.228 ns 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_cv 1.50 % 1.50 % 10 +stringa s = "123456789"; int res = s.to_int_mean 13.7 ns 13.7 ns 10 +stringa s = "123456789"; int res = s.to_int_median 13.7 ns 13.7 ns 10 +stringa s = "123456789"; int res = s.to_int_stddev 0.303 ns 0.303 ns 10 +stringa s = "123456789"; int res = s.to_int_cv 2.21 % 2.21 % 10 +ssa s = "123456789"; int res = s.to_int_mean 13.2 ns 13.2 ns 10 +ssa s = "123456789"; int res = s.to_int_median 13.2 ns 13.2 ns 10 +ssa s = "123456789"; int res = s.to_int_stddev 0.187 ns 0.187 ns 10 +ssa s = "123456789"; int res = s.to_int_cv 1.41 % 1.41 % 10 +lstringa<20> s = "123456789"; int res = s.to_int_mean 12.8 ns 12.8 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_median 12.7 ns 12.7 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_stddev 0.256 ns 0.256 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_cv 2.00 % 2.00 % 10 +----- Convert to unsigned 'abcDef' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_mean 24.2 ns 24.2 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_median 24.1 ns 24.1 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_stddev 0.548 ns 0.548 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_cv 2.27 % 2.27 % 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_mean 9.80 ns 9.80 ns 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_median 9.83 ns 9.83 ns 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_stddev 0.180 ns 0.180 ns 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_cv 1.84 % 1.84 % 10 +stringa s = "abcDef"; int res = s.to_int_mean 11.8 ns 11.8 ns 10 +stringa s = "abcDef"; int res = s.to_int_median 11.8 ns 11.8 ns 10 +stringa s = "abcDef"; int res = s.to_int_stddev 0.179 ns 0.179 ns 10 +stringa s = "abcDef"; int res = s.to_int_cv 1.52 % 1.52 % 10 +ssa s = "abcDef"; int res = s.to_int_mean 11.6 ns 11.6 ns 10 +ssa s = "abcDef"; int res = s.to_int_median 11.6 ns 11.6 ns 10 +ssa s = "abcDef"; int res = s.to_int_stddev 0.327 ns 0.327 ns 10 +ssa s = "abcDef"; int res = s.to_int_cv 2.83 % 2.83 % 10 +lstringa<20> s = "abcDef"; int res = s.to_int_mean 11.5 ns 11.5 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_median 11.5 ns 11.5 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_stddev 0.224 ns 0.224 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_cv 1.95 % 1.95 % 10 +----- Convert to int ' 1234567' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_mean 29.1 ns 29.1 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_median 29.1 ns 29.1 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_stddev 0.554 ns 0.554 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_cv 1.91 % 1.91 % 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_mean 22.1 ns 22.1 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_median 22.0 ns 22.0 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_stddev 0.224 ns 0.224 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_cv 1.01 % 1.01 % 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_mean 15.8 ns 15.8 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_median 15.8 ns 15.8 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_stddev 0.195 ns 0.195 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_cv 1.24 % 1.24 % 10 +-- Append const literal of 16 bytes 64 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << "abbaabbaabbaabba";_mean 1384 ns 1384 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_median 1388 ns 1388 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_stddev 36.8 ns 36.8 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_cv 2.66 % 2.66 % 10 +std::string str; ... str += "abbaabbaabbaabba";_mean 368 ns 368 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_median 372 ns 372 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_stddev 10.2 ns 10.2 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_cv 2.78 % 2.78 % 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_mean 370 ns 370 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_median 371 ns 371 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_stddev 7.32 ns 7.32 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_cv 1.98 % 1.98 % 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_mean 254 ns 254 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_median 254 ns 254 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_stddev 7.63 ns 7.63 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_cv 3.01 % 3.01 % 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_mean 232 ns 232 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_median 230 ns 230 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_stddev 7.81 ns 7.81 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_cv 3.37 % 3.37 % 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_mean 140 ns 140 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_median 139 ns 139 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_stddev 2.35 ns 2.35 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_cv 1.68 % 1.68 % 10 +-- Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_mean 1390 ns 1390 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_median 1373 ns 1373 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_stddev 61.6 ns 61.6 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_cv 4.43 % 4.43 % 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_mean 1298 ns 1298 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_median 1303 ns 1303 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_stddev 25.4 ns 25.4 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_cv 1.95 % 1.95 % 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_mean 425 ns 425 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_median 428 ns 428 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_stddev 8.18 ns 8.18 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_cv 1.92 % 1.92 % 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_mean 367 ns 367 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_median 362 ns 362 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_stddev 13.0 ns 13.0 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_cv 3.55 % 3.55 % 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_mean 323 ns 323 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_median 319 ns 319 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_stddev 11.6 ns 11.6 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_cv 3.58 % 3.58 % 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_mean 241 ns 241 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_median 241 ns 241 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_stddev 4.24 ns 4.24 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_cv 1.76 % 1.76 % 10 +-- Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_mean 73908 ns 73908 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_median 73853 ns 73853 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_stddev 761 ns 761 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_cv 1.03 % 1.03 % 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 77722 ns 77722 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 77751 ns 77751 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 1085 ns 1085 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 1.40 % 1.40 % 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 21112 ns 21112 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 20934 ns 20934 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 636 ns 636 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 3.01 % 3.01 % 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 16124 ns 16124 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 16155 ns 16155 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 368 ns 368 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 2.28 % 2.28 % 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 16129 ns 16129 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 16093 ns 16093 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 441 ns 441 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 2.74 % 2.74 % 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 16145 ns 16145 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 16117 ns 16118 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 500 ns 500 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 3.10 % 3.10 % 10 +-- Append 2 string of 16 bytes 32 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var1 << str_var2;_mean 1393 ns 1393 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_median 1394 ns 1394 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_stddev 17.5 ns 17.5 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_cv 1.25 % 1.25 % 10 +std::string str; ... str += str_var1 + str_var2;_mean 1412 ns 1412 ns 10 +std::string str; ... str += str_var1 + str_var2;_median 1403 ns 1403 ns 10 +std::string str; ... str += str_var1 + str_var2;_stddev 31.2 ns 31.2 ns 10 +std::string str; ... str += str_var1 + str_var2;_cv 2.21 % 2.21 % 10 +lstringa<16> str; ... str += str_var1 + str_var2;_mean 513 ns 513 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_median 513 ns 513 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_stddev 11.8 ns 11.8 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_cv 2.30 % 2.30 % 10 +lstringa<128> str; ... str += str_var1 + str_var2;_mean 443 ns 443 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_median 443 ns 443 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_stddev 9.72 ns 9.72 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_cv 2.20 % 2.20 % 10 +lstringa<512> str; ... str += str_var1 + str_var2;_mean 395 ns 395 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_median 395 ns 395 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_stddev 10.6 ns 10.6 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_cv 2.67 % 2.67 % 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_mean 312 ns 312 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_median 312 ns 312 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_stddev 4.76 ns 4.76 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_cv 1.52 % 1.52 % 10 +-- Append text, number, text --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; str << "test = " << k << " times";_mean 3133 ns 3133 ns 10 +std::stringstream str; str << "test = " << k << " times";_median 3110 ns 3110 ns 10 +std::stringstream str; str << "test = " << k << " times";_stddev 97.9 ns 97.9 ns 10 +std::stringstream str; str << "test = " << k << " times";_cv 3.12 % 3.12 % 10 +std::string str = "test = " + std::to_string(k) + " times";_mean 486 ns 486 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_median 486 ns 486 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_stddev 8.54 ns 8.55 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_cv 1.76 % 1.76 % 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_mean 1424 ns 1424 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_median 1411 ns 1411 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_stddev 30.7 ns 30.7 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_cv 2.16 % 2.16 % 10 +std::string str = std::format("test = {} times", k);_mean 1184 ns 1184 ns 10 +std::string str = std::format("test = {} times", k);_median 1176 ns 1176 ns 10 +std::string str = std::format("test = {} times", k);_stddev 26.6 ns 26.6 ns 10 +std::string str = std::format("test = {} times", k);_cv 2.25 % 2.25 % 10 +lstringa<8> str; str.format("test = {} times", k);_mean 1412 ns 1412 ns 10 +lstringa<8> str; str.format("test = {} times", k);_median 1396 ns 1396 ns 10 +lstringa<8> str; str.format("test = {} times", k);_stddev 46.3 ns 46.3 ns 10 +lstringa<8> str; str.format("test = {} times", k);_cv 3.28 % 3.28 % 10 +lstringa<32> str; str.format("test = {} times", k);_mean 997 ns 997 ns 10 +lstringa<32> str; str.format("test = {} times", k);_median 996 ns 996 ns 10 +lstringa<32> str; str.format("test = {} times", k);_stddev 19.7 ns 19.7 ns 10 +lstringa<32> str; str.format("test = {} times", k);_cv 1.98 % 1.98 % 10 +lstringa<8> str = "test = " + k + " times";_mean 323 ns 323 ns 10 +lstringa<8> str = "test = " + k + " times";_median 322 ns 322 ns 10 +lstringa<8> str = "test = " + k + " times";_stddev 12.6 ns 12.6 ns 10 +lstringa<8> str = "test = " + k + " times";_cv 3.92 % 3.92 % 10 +lstringa<32> str = "test = " + k + " times";_mean 157 ns 157 ns 10 +lstringa<32> str = "test = " + k + " times";_median 158 ns 158 ns 10 +lstringa<32> str = "test = " + k + " times";_stddev 2.50 ns 2.50 ns 10 +lstringa<32> str = "test = " + k + " times";_cv 1.59 % 1.59 % 10 +stringa str = "test = " + k + " times";_mean 152 ns 152 ns 10 +stringa str = "test = " + k + " times";_median 151 ns 151 ns 10 +stringa str = "test = " + k + " times";_stddev 3.32 ns 3.32 ns 10 +stringa str = "test = " + k + " times";_cv 2.18 % 2.18 % 10 +-- Split text and convert to int --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string::find + substr + std::strtol_mean 268 ns 268 ns 10 +std::string::find + substr + std::strtol_median 266 ns 266 ns 10 +std::string::find + substr + std::strtol_stddev 8.11 ns 8.11 ns 10 +std::string::find + substr + std::strtol_cv 3.03 % 3.03 % 10 +ssa::splitter + ssa::as_int_mean 161 ns 161 ns 10 +ssa::splitter + ssa::as_int_median 161 ns 161 ns 10 +ssa::splitter + ssa::as_int_stddev 2.57 ns 2.57 ns 10 +ssa::splitter + ssa::as_int_cv 1.59 % 1.59 % 10 +ssa::splitf + functor_mean 180 ns 180 ns 10 +ssa::splitf + functor_median 180 ns 180 ns 10 +ssa::splitf + functor_stddev 3.96 ns 3.96 ns 10 +ssa::splitf + functor_cv 2.20 % 2.20 % 10 +-- Replace symbols in text ~400 symbols --/repeats:1 0.000 ns 0.000 ns 1000000000 +Naive (and wrong) replace symbols with std::string find + replace_mean 859 ns 859 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_median 863 ns 863 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_stddev 15.1 ns 15.1 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_cv 1.76 % 1.76 % 10 +replace symbols with std::string find_first_of + replace_mean 2541 ns 2541 ns 10 +replace symbols with std::string find_first_of + replace_median 2536 ns 2536 ns 10 +replace symbols with std::string find_first_of + replace_stddev 46.5 ns 46.5 ns 10 +replace symbols with std::string find_first_of + replace_cv 1.83 % 1.83 % 10 +replace symbols with std::string_view find_first_of + copy_mean 2719 ns 2719 ns 10 +replace symbols with std::string_view find_first_of + copy_median 2686 ns 2686 ns 10 +replace symbols with std::string_view find_first_of + copy_stddev 132 ns 132 ns 10 +replace symbols with std::string_view find_first_of + copy_cv 4.86 % 4.86 % 10 +replace runtime symbols with string expressions and without remembering all search results_mean 1253 ns 1253 ns 10 +replace runtime symbols with string expressions and without remembering all search results_median 1248 ns 1248 ns 10 +replace runtime symbols with string expressions and without remembering all search results_stddev 19.8 ns 19.8 ns 10 +replace runtime symbols with string expressions and without remembering all search results_cv 1.58 % 1.58 % 10 +replace runtime symbols with simstr and memorization of all search results_mean 1026 ns 1026 ns 10 +replace runtime symbols with simstr and memorization of all search results_median 1007 ns 1007 ns 10 +replace runtime symbols with simstr and memorization of all search results_stddev 52.6 ns 52.6 ns 10 +replace runtime symbols with simstr and memorization of all search results_cv 5.13 % 5.13 % 10 +replace const symbols with string expressions and without remembering all search results_mean 1150 ns 1150 ns 10 +replace const symbols with string expressions and without remembering all search results_median 1150 ns 1150 ns 10 +replace const symbols with string expressions and without remembering all search results_stddev 13.8 ns 13.8 ns 10 +replace const symbols with string expressions and without remembering all search results_cv 1.20 % 1.20 % 10 +replace const symbols with string expressions and memorization of all search results_mean 897 ns 897 ns 10 +replace const symbols with string expressions and memorization of all search results_median 892 ns 892 ns 10 +replace const symbols with string expressions and memorization of all search results_stddev 16.3 ns 16.3 ns 10 +replace const symbols with string expressions and memorization of all search results_cv 1.82 % 1.82 % 10 +-- Replace symbols in text ~40 symbols --/repeats:1 0.000 ns 0.000 ns 1000000000 +Short Naive (and wrong) replace symbols with std::string find + replace_mean 165 ns 165 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_median 165 ns 165 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_stddev 2.38 ns 2.38 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_cv 1.44 % 1.44 % 10 +Short replace symbols with std::string find_first_of + replace_mean 312 ns 312 ns 10 +Short replace symbols with std::string find_first_of + replace_median 312 ns 312 ns 10 +Short replace symbols with std::string find_first_of + replace_stddev 4.94 ns 4.94 ns 10 +Short replace symbols with std::string find_first_of + replace_cv 1.58 % 1.58 % 10 +Short replace symbols with std::string_view find_first_of + copy_mean 338 ns 338 ns 10 +Short replace symbols with std::string_view find_first_of + copy_median 339 ns 339 ns 10 +Short replace symbols with std::string_view find_first_of + copy_stddev 4.87 ns 4.87 ns 10 +Short replace symbols with std::string_view find_first_of + copy_cv 1.44 % 1.44 % 10 +Short replace runtime symbols with string expressions and without remembering all search results_mean 165 ns 165 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_median 166 ns 166 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_stddev 2.88 ns 2.88 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_cv 1.74 % 1.74 % 10 +Short replace runtime symbols with simstr and memorization of all search results_mean 188 ns 188 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_median 185 ns 185 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_stddev 5.08 ns 5.08 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_cv 2.71 % 2.71 % 10 +Short replace const symbols with string expressions and without remembering all search results_mean 146 ns 146 ns 10 +Short replace const symbols with string expressions and without remembering all search results_median 145 ns 145 ns 10 +Short replace const symbols with string expressions and without remembering all search results_stddev 4.26 ns 4.26 ns 10 +Short replace const symbols with string expressions and without remembering all search results_cv 2.93 % 2.93 % 10 +Short replace const symbols with string expressions and memorization of all search results_mean 150 ns 150 ns 10 +Short replace const symbols with string expressions and memorization of all search results_median 148 ns 148 ns 10 +Short replace const symbols with string expressions and memorization of all search results_stddev 6.96 ns 6.96 ns 10 +Short replace const symbols with string expressions and memorization of all search results_cv 4.65 % 4.65 % 10 +----- Replace All Str To Longer Size ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +replace bb to ---- in std::string|64_mean 161 ns 161 ns 10 +replace bb to ---- in std::string|64_median 162 ns 162 ns 10 +replace bb to ---- in std::string|64_stddev 3.66 ns 3.66 ns 10 +replace bb to ---- in std::string|64_cv 2.27 % 2.27 % 10 +replace bb to ---- in std::string|256_mean 541 ns 541 ns 10 +replace bb to ---- in std::string|256_median 543 ns 543 ns 10 +replace bb to ---- in std::string|256_stddev 7.23 ns 7.23 ns 10 +replace bb to ---- in std::string|256_cv 1.33 % 1.33 % 10 +replace bb to ---- in std::string|512_mean 1075 ns 1075 ns 10 +replace bb to ---- in std::string|512_median 1065 ns 1065 ns 10 +replace bb to ---- in std::string|512_stddev 29.7 ns 29.7 ns 10 +replace bb to ---- in std::string|512_cv 2.77 % 2.77 % 10 +replace bb to ---- in std::string|1024_mean 2344 ns 2344 ns 10 +replace bb to ---- in std::string|1024_median 2329 ns 2329 ns 10 +replace bb to ---- in std::string|1024_stddev 107 ns 107 ns 10 +replace bb to ---- in std::string|1024_cv 4.57 % 4.57 % 10 +replace bb to ---- in std::string|2048_mean 6366 ns 6366 ns 10 +replace bb to ---- in std::string|2048_median 6592 ns 6592 ns 10 +replace bb to ---- in std::string|2048_stddev 444 ns 444 ns 10 +replace bb to ---- in std::string|2048_cv 6.97 % 6.97 % 10 +replace bb to ---- in lstringa<8>|64_mean 145 ns 145 ns 10 +replace bb to ---- in lstringa<8>|64_median 144 ns 144 ns 10 +replace bb to ---- in lstringa<8>|64_stddev 3.85 ns 3.85 ns 10 +replace bb to ---- in lstringa<8>|64_cv 2.66 % 2.66 % 10 +replace bb to ---- in lstringa<8>|256_mean 438 ns 438 ns 10 +replace bb to ---- in lstringa<8>|256_median 438 ns 438 ns 10 +replace bb to ---- in lstringa<8>|256_stddev 7.46 ns 7.46 ns 10 +replace bb to ---- in lstringa<8>|256_cv 1.70 % 1.70 % 10 +replace bb to ---- in lstringa<8>|512_mean 824 ns 824 ns 10 +replace bb to ---- in lstringa<8>|512_median 820 ns 820 ns 10 +replace bb to ---- in lstringa<8>|512_stddev 29.8 ns 29.8 ns 10 +replace bb to ---- in lstringa<8>|512_cv 3.62 % 3.62 % 10 +replace bb to ---- in lstringa<8>|1024_mean 1662 ns 1662 ns 10 +replace bb to ---- in lstringa<8>|1024_median 1661 ns 1661 ns 10 +replace bb to ---- in lstringa<8>|1024_stddev 28.8 ns 28.8 ns 10 +replace bb to ---- in lstringa<8>|1024_cv 1.73 % 1.73 % 10 +replace bb to ---- in lstringa<8>|2048_mean 3108 ns 3108 ns 10 +replace bb to ---- in lstringa<8>|2048_median 3101 ns 3101 ns 10 +replace bb to ---- in lstringa<8>|2048_stddev 44.7 ns 44.7 ns 10 +replace bb to ---- in lstringa<8>|2048_cv 1.44 % 1.44 % 10 +replace bb to ---- by init stringa|64_mean 116 ns 116 ns 10 +replace bb to ---- by init stringa|64_median 116 ns 116 ns 10 +replace bb to ---- by init stringa|64_stddev 4.03 ns 4.03 ns 10 +replace bb to ---- by init stringa|64_cv 3.46 % 3.46 % 10 +replace bb to ---- by init stringa|256_mean 389 ns 389 ns 10 +replace bb to ---- by init stringa|256_median 387 ns 387 ns 10 +replace bb to ---- by init stringa|256_stddev 8.05 ns 8.05 ns 10 +replace bb to ---- by init stringa|256_cv 2.07 % 2.07 % 10 +replace bb to ---- by init stringa|512_mean 797 ns 797 ns 10 +replace bb to ---- by init stringa|512_median 794 ns 794 ns 10 +replace bb to ---- by init stringa|512_stddev 18.1 ns 18.1 ns 10 +replace bb to ---- by init stringa|512_cv 2.27 % 2.27 % 10 +replace bb to ---- by init stringa|1024_mean 1629 ns 1629 ns 10 +replace bb to ---- by init stringa|1024_median 1606 ns 1606 ns 10 +replace bb to ---- by init stringa|1024_stddev 68.9 ns 68.9 ns 10 +replace bb to ---- by init stringa|1024_cv 4.23 % 4.23 % 10 +replace bb to ---- by init stringa|2048_mean 3125 ns 3125 ns 10 +replace bb to ---- by init stringa|2048_median 3104 ns 3104 ns 10 +replace bb to ---- by init stringa|2048_stddev 76.1 ns 76.1 ns 10 +replace bb to ---- by init stringa|2048_cv 2.43 % 2.43 % 10 +----- Replace All Str To Same Size ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +replace bb to -- in std::string|64_mean 129 ns 129 ns 10 +replace bb to -- in std::string|64_median 128 ns 128 ns 10 +replace bb to -- in std::string|64_stddev 2.39 ns 2.39 ns 10 +replace bb to -- in std::string|64_cv 1.85 % 1.85 % 10 +replace bb to -- in std::string|256_mean 404 ns 404 ns 10 +replace bb to -- in std::string|256_median 404 ns 404 ns 10 +replace bb to -- in std::string|256_stddev 8.73 ns 8.73 ns 10 +replace bb to -- in std::string|256_cv 2.16 % 2.16 % 10 +replace bb to -- in std::string|512_mean 815 ns 815 ns 10 +replace bb to -- in std::string|512_median 818 ns 818 ns 10 +replace bb to -- in std::string|512_stddev 13.4 ns 13.4 ns 10 +replace bb to -- in std::string|512_cv 1.65 % 1.65 % 10 +replace bb to -- in std::string|1024_mean 1489 ns 1489 ns 10 +replace bb to -- in std::string|1024_median 1486 ns 1486 ns 10 +replace bb to -- in std::string|1024_stddev 31.5 ns 31.5 ns 10 +replace bb to -- in std::string|1024_cv 2.12 % 2.12 % 10 +replace bb to -- in std::string|2048_mean 3100 ns 3100 ns 10 +replace bb to -- in std::string|2048_median 3097 ns 3097 ns 10 +replace bb to -- in std::string|2048_stddev 70.1 ns 70.1 ns 10 +replace bb to -- in std::string|2048_cv 2.26 % 2.26 % 10 +replace bb to -- in lstringa<8>|64_mean 101 ns 101 ns 10 +replace bb to -- in lstringa<8>|64_median 102 ns 102 ns 10 +replace bb to -- in lstringa<8>|64_stddev 1.73 ns 1.73 ns 10 +replace bb to -- in lstringa<8>|64_cv 1.70 % 1.70 % 10 +replace bb to -- in lstringa<8>|256_mean 302 ns 302 ns 10 +replace bb to -- in lstringa<8>|256_median 301 ns 301 ns 10 +replace bb to -- in lstringa<8>|256_stddev 8.49 ns 8.49 ns 10 +replace bb to -- in lstringa<8>|256_cv 2.81 % 2.81 % 10 +replace bb to -- in lstringa<8>|512_mean 579 ns 579 ns 10 +replace bb to -- in lstringa<8>|512_median 562 ns 562 ns 10 +replace bb to -- in lstringa<8>|512_stddev 51.0 ns 51.0 ns 10 +replace bb to -- in lstringa<8>|512_cv 8.81 % 8.81 % 10 +replace bb to -- in lstringa<8>|1024_mean 1181 ns 1181 ns 10 +replace bb to -- in lstringa<8>|1024_median 1166 ns 1166 ns 10 +replace bb to -- in lstringa<8>|1024_stddev 58.8 ns 58.8 ns 10 +replace bb to -- in lstringa<8>|1024_cv 4.98 % 4.98 % 10 +replace bb to -- in lstringa<8>|2048_mean 2181 ns 2181 ns 10 +replace bb to -- in lstringa<8>|2048_median 2186 ns 2186 ns 10 +replace bb to -- in lstringa<8>|2048_stddev 42.1 ns 42.1 ns 10 +replace bb to -- in lstringa<8>|2048_cv 1.93 % 1.93 % 10 +replace bb to -- by init stringa|64_mean 82.9 ns 82.9 ns 10 +replace bb to -- by init stringa|64_median 82.6 ns 82.6 ns 10 +replace bb to -- by init stringa|64_stddev 1.53 ns 1.53 ns 10 +replace bb to -- by init stringa|64_cv 1.84 % 1.84 % 10 +replace bb to -- by init stringa|256_mean 219 ns 219 ns 10 +replace bb to -- by init stringa|256_median 218 ns 218 ns 10 +replace bb to -- by init stringa|256_stddev 2.33 ns 2.33 ns 10 +replace bb to -- by init stringa|256_cv 1.07 % 1.07 % 10 +replace bb to -- by init stringa|512_mean 447 ns 447 ns 10 +replace bb to -- by init stringa|512_median 448 ns 448 ns 10 +replace bb to -- by init stringa|512_stddev 5.79 ns 5.79 ns 10 +replace bb to -- by init stringa|512_cv 1.30 % 1.30 % 10 +replace bb to -- by init stringa|1024_mean 880 ns 880 ns 10 +replace bb to -- by init stringa|1024_median 877 ns 877 ns 10 +replace bb to -- by init stringa|1024_stddev 19.6 ns 19.6 ns 10 +replace bb to -- by init stringa|1024_cv 2.23 % 2.23 % 10 +replace bb to -- by init stringa|2048_mean 1654 ns 1654 ns 10 +replace bb to -- by init stringa|2048_median 1647 ns 1647 ns 10 +replace bb to -- by init stringa|2048_stddev 38.5 ns 38.5 ns 10 +replace bb to -- by init stringa|2048_cv 2.33 % 2.33 % 10 +----- Hash Map insert and find ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +hashStrMapA emplace & find stringa;_mean 3718900 ns 3718917 ns 10 +hashStrMapA emplace & find stringa;_median 3693440 ns 3693461 ns 10 +hashStrMapA emplace & find stringa;_stddev 53764 ns 53763 ns 10 +hashStrMapA emplace & find stringa;_cv 1.45 % 1.45 % 10 +std::unordered_map emplace & find std::string;_mean 3691442 ns 3691453 ns 10 +std::unordered_map emplace & find std::string;_median 3673099 ns 3673111 ns 10 +std::unordered_map emplace & find std::string;_stddev 139694 ns 139694 ns 10 +std::unordered_map emplace & find std::string;_cv 3.78 % 3.78 % 10 +hashStrMapA emplace & find ssa;_mean 3719844 ns 3719860 ns 10 +hashStrMapA emplace & find ssa;_median 3711079 ns 3711094 ns 10 +hashStrMapA emplace & find ssa;_stddev 26128 ns 26129 ns 10 +hashStrMapA emplace & find ssa;_cv 0.70 % 0.70 % 10 +std::unordered_map emplace & find std::string_view;_mean 4115786 ns 4115803 ns 10 +std::unordered_map emplace & find std::string_view;_median 4138618 ns 4138635 ns 10 +std::unordered_map emplace & find std::string_view;_stddev 84101 ns 84103 ns 10 +std::unordered_map emplace & find std::string_view;_cv 2.04 % 2.04 % 10 +----- Build Full Func Name ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +Build func full name std::string;_mean 733 ns 733 ns 10 +Build func full name std::string;_median 733 ns 733 ns 10 +Build func full name std::string;_stddev 10.6 ns 10.6 ns 10 +Build func full name std::string;_cv 1.44 % 1.44 % 10 +Build func full name std::string 1;_mean 837 ns 837 ns 10 +Build func full name std::string 1;_median 832 ns 832 ns 10 +Build func full name std::string 1;_stddev 20.2 ns 20.2 ns 10 +Build func full name std::string 1;_cv 2.41 % 2.41 % 10 +Build func full name std::stream;_mean 2608 ns 2608 ns 10 +Build func full name std::stream;_median 2618 ns 2618 ns 10 +Build func full name std::stream;_stddev 46.4 ns 46.4 ns 10 +Build func full name std::stream;_cv 1.78 % 1.78 % 10 +Build func full name stringa;_mean 512 ns 512 ns 10 +Build func full name stringa;_median 509 ns 509 ns 10 +Build func full name stringa;_stddev 7.69 ns 7.69 ns 10 +Build func full name stringa;_cv 1.50 % 1.50 % 10 +Build func full name stringa 1;_mean 657 ns 657 ns 10 +Build func full name stringa 1;_median 656 ns 656 ns 10 +Build func full name stringa 1;_stddev 11.9 ns 11.9 ns 10 +Build func full name stringa 1;_cv 1.80 % 1.80 % 10 diff --git a/bench/results/001-Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13.txt b/bench/results/001-Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13.txt new file mode 100644 index 0000000..e69963b --- /dev/null +++ b/bench/results/001-Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13.txt @@ -0,0 +1,778 @@ +2025-08-06T13:47:54+03:00 +Running ./benchStr +Run on (32 X 2494.22 MHz CPU s) +CPU Caches: + L1 Data 32 KiB (x16) + L1 Instruction 32 KiB (x16) + L2 Unified 256 KiB (x16) + L3 Unified 40960 KiB (x1) +Load Average: 0.00, 0.00, 0.00 +-------------------------------------------------------------------------------------------------------------------------------------------------------- +Benchmark Time CPU Iterations +-------------------------------------------------------------------------------------------------------------------------------------------------------- +----- Create Empty Str ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e;_mean 1.19 ns 1.19 ns 10 +std::string e;_median 1.17 ns 1.17 ns 10 +std::string e;_stddev 0.087 ns 0.087 ns 10 +std::string e;_cv 7.32 % 7.32 % 10 +std::string_view e;_mean 0.759 ns 0.759 ns 10 +std::string_view e;_median 0.740 ns 0.740 ns 10 +std::string_view e;_stddev 0.033 ns 0.033 ns 10 +std::string_view e;_cv 4.40 % 4.40 % 10 +ssa e;_mean 0.185 ns 0.185 ns 10 +ssa e;_median 0.185 ns 0.185 ns 10 +ssa e;_stddev 0.004 ns 0.004 ns 10 +ssa e;_cv 2.05 % 2.05 % 10 +stringa e;_mean 0.759 ns 0.759 ns 10 +stringa e;_median 0.756 ns 0.756 ns 10 +stringa e;_stddev 0.027 ns 0.027 ns 10 +stringa e;_cv 3.57 % 3.57 % 10 +lstringa<20> e;_mean 1.11 ns 1.11 ns 10 +lstringa<20> e;_median 1.11 ns 1.11 ns 10 +lstringa<20> e;_stddev 0.017 ns 0.017 ns 10 +lstringa<20> e;_cv 1.52 % 1.52 % 10 +lstringa<40> e;_mean 1.13 ns 1.13 ns 10 +lstringa<40> e;_median 1.14 ns 1.14 ns 10 +lstringa<40> e;_stddev 0.025 ns 0.025 ns 10 +lstringa<40> e;_cv 2.19 % 2.19 % 10 +----- Create Str from short literal (9 symbols) --------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "Test text";_mean 1.88 ns 1.88 ns 10 +std::string e = "Test text";_median 1.87 ns 1.87 ns 10 +std::string e = "Test text";_stddev 0.047 ns 0.047 ns 10 +std::string e = "Test text";_cv 2.47 % 2.47 % 10 +std::string_view e = "Test text";_mean 0.757 ns 0.757 ns 10 +std::string_view e = "Test text";_median 0.750 ns 0.750 ns 10 +std::string_view e = "Test text";_stddev 0.031 ns 0.031 ns 10 +std::string_view e = "Test text";_cv 4.04 % 4.04 % 10 +ssa e = "Test text";_mean 0.746 ns 0.746 ns 10 +ssa e = "Test text";_median 0.739 ns 0.739 ns 10 +ssa e = "Test text";_stddev 0.016 ns 0.016 ns 10 +ssa e = "Test text";_cv 2.14 % 2.14 % 10 +stringa e = "Test text";_mean 1.12 ns 1.12 ns 10 +stringa e = "Test text";_median 1.12 ns 1.12 ns 10 +stringa e = "Test text";_stddev 0.027 ns 0.027 ns 10 +stringa e = "Test text";_cv 2.38 % 2.38 % 10 +lstringa<20> e = "Test text";_mean 1.87 ns 1.87 ns 10 +lstringa<20> e = "Test text";_median 1.86 ns 1.86 ns 10 +lstringa<20> e = "Test text";_stddev 0.049 ns 0.049 ns 10 +lstringa<20> e = "Test text";_cv 2.64 % 2.64 % 10 +lstringa<40> e = "Test text";_mean 1.91 ns 1.91 ns 10 +lstringa<40> e = "Test text";_median 1.88 ns 1.88 ns 10 +lstringa<40> e = "Test text";_stddev 0.082 ns 0.082 ns 10 +lstringa<40> e = "Test text";_cv 4.30 % 4.30 % 10 +----- Create Str from long literal (30 symbols) ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "123456789012345678901234567890";_mean 18.7 ns 18.7 ns 10 +std::string e = "123456789012345678901234567890";_median 18.5 ns 18.5 ns 10 +std::string e = "123456789012345678901234567890";_stddev 0.629 ns 0.629 ns 10 +std::string e = "123456789012345678901234567890";_cv 3.36 % 3.36 % 10 +std::string_view e = "123456789012345678901234567890";_mean 0.751 ns 0.751 ns 10 +std::string_view e = "123456789012345678901234567890";_median 0.741 ns 0.741 ns 10 +std::string_view e = "123456789012345678901234567890";_stddev 0.023 ns 0.023 ns 10 +std::string_view e = "123456789012345678901234567890";_cv 3.03 % 3.03 % 10 +ssa e = "123456789012345678901234567890";_mean 0.754 ns 0.754 ns 10 +ssa e = "123456789012345678901234567890";_median 0.758 ns 0.758 ns 10 +ssa e = "123456789012345678901234567890";_stddev 0.021 ns 0.021 ns 10 +ssa e = "123456789012345678901234567890";_cv 2.79 % 2.79 % 10 +stringa e = "123456789012345678901234567890";_mean 1.13 ns 1.13 ns 10 +stringa e = "123456789012345678901234567890";_median 1.12 ns 1.12 ns 10 +stringa e = "123456789012345678901234567890";_stddev 0.026 ns 0.026 ns 10 +stringa e = "123456789012345678901234567890";_cv 2.29 % 2.29 % 10 +lstringa<20> e = "123456789012345678901234567890";_mean 19.6 ns 19.6 ns 10 +lstringa<20> e = "123456789012345678901234567890";_median 19.3 ns 19.3 ns 10 +lstringa<20> e = "123456789012345678901234567890";_stddev 0.546 ns 0.546 ns 10 +lstringa<20> e = "123456789012345678901234567890";_cv 2.78 % 2.78 % 10 +lstringa<40> e = "123456789012345678901234567890";_mean 2.59 ns 2.59 ns 10 +lstringa<40> e = "123456789012345678901234567890";_median 2.56 ns 2.56 ns 10 +lstringa<40> e = "123456789012345678901234567890";_stddev 0.055 ns 0.055 ns 10 +lstringa<40> e = "123456789012345678901234567890";_cv 2.14 % 2.14 % 10 +----- Create copy of Str with 9 symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "Test text"; auto c{e};_mean 4.91 ns 4.91 ns 10 +std::string e = "Test text"; auto c{e};_median 4.87 ns 4.87 ns 10 +std::string e = "Test text"; auto c{e};_stddev 0.160 ns 0.160 ns 10 +std::string e = "Test text"; auto c{e};_cv 3.26 % 3.26 % 10 +std::string_view e = "Test text"; auto c{e};_mean 0.377 ns 0.377 ns 10 +std::string_view e = "Test text"; auto c{e};_median 0.375 ns 0.375 ns 10 +std::string_view e = "Test text"; auto c{e};_stddev 0.015 ns 0.015 ns 10 +std::string_view e = "Test text"; auto c{e};_cv 3.90 % 3.90 % 10 +ssa e = "Test text"; auto c{e};_mean 0.378 ns 0.378 ns 10 +ssa e = "Test text"; auto c{e};_median 0.372 ns 0.372 ns 10 +ssa e = "Test text"; auto c{e};_stddev 0.015 ns 0.015 ns 10 +ssa e = "Test text"; auto c{e};_cv 3.95 % 3.95 % 10 +stringa e = "Test text"; auto c{e};_mean 1.14 ns 1.14 ns 10 +stringa e = "Test text"; auto c{e};_median 1.13 ns 1.13 ns 10 +stringa e = "Test text"; auto c{e};_stddev 0.031 ns 0.031 ns 10 +stringa e = "Test text"; auto c{e};_cv 2.70 % 2.70 % 10 +lstringa<20> e = "Test text"; auto c{e};_mean 4.84 ns 4.84 ns 10 +lstringa<20> e = "Test text"; auto c{e};_median 4.81 ns 4.81 ns 10 +lstringa<20> e = "Test text"; auto c{e};_stddev 0.090 ns 0.090 ns 10 +lstringa<20> e = "Test text"; auto c{e};_cv 1.85 % 1.85 % 10 +lstringa<40> e = "Test text"; auto c{e};_mean 4.60 ns 4.60 ns 10 +lstringa<40> e = "Test text"; auto c{e};_median 4.54 ns 4.54 ns 10 +lstringa<40> e = "Test text"; auto c{e};_stddev 0.189 ns 0.189 ns 10 +lstringa<40> e = "Test text"; auto c{e};_cv 4.10 % 4.10 % 10 +----- Create copy of Str with 30 symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "123456789012345678901234567890"; auto c{e};_mean 24.2 ns 24.2 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_median 24.0 ns 24.0 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_stddev 0.450 ns 0.450 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_cv 1.86 % 1.86 % 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_mean 0.746 ns 0.746 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_median 0.741 ns 0.741 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_stddev 0.021 ns 0.021 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_cv 2.85 % 2.85 % 10 +ssa e = "123456789012345678901234567890"; auto c{e};_mean 0.744 ns 0.744 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_median 0.741 ns 0.741 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_stddev 0.010 ns 0.010 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_cv 1.35 % 1.35 % 10 +stringa e = "123456789012345678901234567890"; auto c{e};_mean 1.13 ns 1.13 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_median 1.13 ns 1.13 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_stddev 0.030 ns 0.030 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_cv 2.63 % 2.63 % 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_mean 24.4 ns 24.4 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_median 24.3 ns 24.3 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_stddev 0.796 ns 0.796 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_cv 3.26 % 3.26 % 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_mean 5.62 ns 5.62 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_median 5.50 ns 5.50 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_stddev 0.242 ns 0.242 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_cv 4.30 % 4.30 % 10 +----- Find 9 symbols text in end of 99 symbols text ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string::find;_mean 7.11 ns 7.11 ns 10 +std::string::find;_median 7.08 ns 7.08 ns 10 +std::string::find;_stddev 0.117 ns 0.117 ns 10 +std::string::find;_cv 1.65 % 1.65 % 10 +std::string_view::find;_mean 6.43 ns 6.43 ns 10 +std::string_view::find;_median 6.38 ns 6.38 ns 10 +std::string_view::find;_stddev 0.242 ns 0.242 ns 10 +std::string_view::find;_cv 3.76 % 3.76 % 10 +ssa::find;_mean 6.47 ns 6.47 ns 10 +ssa::find;_median 6.41 ns 6.41 ns 10 +ssa::find;_stddev 0.241 ns 0.241 ns 10 +ssa::find;_cv 3.72 % 3.72 % 10 +stringa::find;_mean 6.83 ns 6.83 ns 10 +stringa::find;_median 6.74 ns 6.74 ns 10 +stringa::find;_stddev 0.269 ns 0.269 ns 10 +stringa::find;_cv 3.94 % 3.94 % 10 +lstringa<20>::find;_mean 6.88 ns 6.88 ns 10 +lstringa<20>::find;_median 6.78 ns 6.78 ns 10 +lstringa<20>::find;_stddev 0.288 ns 0.288 ns 10 +lstringa<20>::find;_cv 4.18 % 4.18 % 10 +lstringa<40>::find;_mean 6.80 ns 6.80 ns 10 +lstringa<40>::find;_median 6.75 ns 6.75 ns 10 +lstringa<40>::find;_stddev 0.164 ns 0.164 ns 10 +lstringa<40>::find;_cv 2.41 % 2.41 % 10 +------- Copy not literal Str with N symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string copy{str_with_len_N};/15_mean 7.34 ns 7.34 ns 10 +std::string copy{str_with_len_N};/15_median 7.19 ns 7.19 ns 10 +std::string copy{str_with_len_N};/15_stddev 0.277 ns 0.277 ns 10 +std::string copy{str_with_len_N};/15_cv 3.77 % 3.77 % 10 +std::string copy{str_with_len_N};/16_mean 24.8 ns 24.8 ns 10 +std::string copy{str_with_len_N};/16_median 24.7 ns 24.8 ns 10 +std::string copy{str_with_len_N};/16_stddev 0.837 ns 0.837 ns 10 +std::string copy{str_with_len_N};/16_cv 3.37 % 3.37 % 10 +std::string copy{str_with_len_N};/23_mean 25.3 ns 25.3 ns 10 +std::string copy{str_with_len_N};/23_median 25.6 ns 25.6 ns 10 +std::string copy{str_with_len_N};/23_stddev 0.737 ns 0.737 ns 10 +std::string copy{str_with_len_N};/23_cv 2.92 % 2.92 % 10 +std::string copy{str_with_len_N};/24_mean 24.6 ns 24.6 ns 10 +std::string copy{str_with_len_N};/24_median 24.6 ns 24.6 ns 10 +std::string copy{str_with_len_N};/24_stddev 0.566 ns 0.566 ns 10 +std::string copy{str_with_len_N};/24_cv 2.30 % 2.30 % 10 +std::string copy{str_with_len_N};/32_mean 23.9 ns 23.9 ns 10 +std::string copy{str_with_len_N};/32_median 23.9 ns 23.9 ns 10 +std::string copy{str_with_len_N};/32_stddev 0.236 ns 0.236 ns 10 +std::string copy{str_with_len_N};/32_cv 0.99 % 0.99 % 10 +std::string copy{str_with_len_N};/64_mean 24.1 ns 24.1 ns 10 +std::string copy{str_with_len_N};/64_median 23.9 ns 23.9 ns 10 +std::string copy{str_with_len_N};/64_stddev 0.627 ns 0.627 ns 10 +std::string copy{str_with_len_N};/64_cv 2.60 % 2.60 % 10 +std::string copy{str_with_len_N};/128_mean 26.1 ns 26.1 ns 10 +std::string copy{str_with_len_N};/128_median 26.1 ns 26.1 ns 10 +std::string copy{str_with_len_N};/128_stddev 0.285 ns 0.285 ns 10 +std::string copy{str_with_len_N};/128_cv 1.09 % 1.09 % 10 +std::string copy{str_with_len_N};/256_mean 26.6 ns 26.6 ns 10 +std::string copy{str_with_len_N};/256_median 26.5 ns 26.5 ns 10 +std::string copy{str_with_len_N};/256_stddev 0.690 ns 0.690 ns 10 +std::string copy{str_with_len_N};/256_cv 2.60 % 2.60 % 10 +std::string copy{str_with_len_N};/512_mean 30.8 ns 30.8 ns 10 +std::string copy{str_with_len_N};/512_median 30.3 ns 30.3 ns 10 +std::string copy{str_with_len_N};/512_stddev 1.13 ns 1.13 ns 10 +std::string copy{str_with_len_N};/512_cv 3.68 % 3.68 % 10 +std::string copy{str_with_len_N};/1024_mean 41.2 ns 41.2 ns 10 +std::string copy{str_with_len_N};/1024_median 40.9 ns 40.9 ns 10 +std::string copy{str_with_len_N};/1024_stddev 1.67 ns 1.67 ns 10 +std::string copy{str_with_len_N};/1024_cv 4.06 % 4.06 % 10 +std::string copy{str_with_len_N};/2048_mean 111 ns 111 ns 10 +std::string copy{str_with_len_N};/2048_median 111 ns 111 ns 10 +std::string copy{str_with_len_N};/2048_stddev 7.17 ns 7.17 ns 10 +std::string copy{str_with_len_N};/2048_cv 6.44 % 6.44 % 10 +std::string copy{str_with_len_N};/4096_mean 139 ns 139 ns 10 +std::string copy{str_with_len_N};/4096_median 140 ns 140 ns 10 +std::string copy{str_with_len_N};/4096_stddev 7.50 ns 7.50 ns 10 +std::string copy{str_with_len_N};/4096_cv 5.41 % 5.41 % 10 +stringa copy{str_with_len_N};/15_mean 1.11 ns 1.11 ns 10 +stringa copy{str_with_len_N};/15_median 1.10 ns 1.10 ns 10 +stringa copy{str_with_len_N};/15_stddev 0.023 ns 0.023 ns 10 +stringa copy{str_with_len_N};/15_cv 2.05 % 2.05 % 10 +stringa copy{str_with_len_N};/16_mean 1.12 ns 1.12 ns 10 +stringa copy{str_with_len_N};/16_median 1.11 ns 1.11 ns 10 +stringa copy{str_with_len_N};/16_stddev 0.032 ns 0.032 ns 10 +stringa copy{str_with_len_N};/16_cv 2.87 % 2.87 % 10 +stringa copy{str_with_len_N};/23_mean 1.11 ns 1.11 ns 10 +stringa copy{str_with_len_N};/23_median 1.10 ns 1.10 ns 10 +stringa copy{str_with_len_N};/23_stddev 0.023 ns 0.023 ns 10 +stringa copy{str_with_len_N};/23_cv 2.11 % 2.11 % 10 +stringa copy{str_with_len_N};/24_mean 16.2 ns 16.2 ns 10 +stringa copy{str_with_len_N};/24_median 16.0 ns 16.0 ns 10 +stringa copy{str_with_len_N};/24_stddev 0.541 ns 0.541 ns 10 +stringa copy{str_with_len_N};/24_cv 3.33 % 3.33 % 10 +stringa copy{str_with_len_N};/32_mean 16.2 ns 16.2 ns 10 +stringa copy{str_with_len_N};/32_median 16.0 ns 16.0 ns 10 +stringa copy{str_with_len_N};/32_stddev 0.374 ns 0.374 ns 10 +stringa copy{str_with_len_N};/32_cv 2.32 % 2.32 % 10 +stringa copy{str_with_len_N};/64_mean 16.8 ns 16.8 ns 10 +stringa copy{str_with_len_N};/64_median 16.6 ns 16.6 ns 10 +stringa copy{str_with_len_N};/64_stddev 0.604 ns 0.604 ns 10 +stringa copy{str_with_len_N};/64_cv 3.59 % 3.59 % 10 +stringa copy{str_with_len_N};/128_mean 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/128_median 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/128_stddev 0.263 ns 0.263 ns 10 +stringa copy{str_with_len_N};/128_cv 1.62 % 1.62 % 10 +stringa copy{str_with_len_N};/256_mean 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/256_median 16.2 ns 16.2 ns 10 +stringa copy{str_with_len_N};/256_stddev 0.244 ns 0.244 ns 10 +stringa copy{str_with_len_N};/256_cv 1.50 % 1.50 % 10 +stringa copy{str_with_len_N};/512_mean 16.4 ns 16.4 ns 10 +stringa copy{str_with_len_N};/512_median 16.3 ns 16.3 ns 10 +stringa copy{str_with_len_N};/512_stddev 0.290 ns 0.290 ns 10 +stringa copy{str_with_len_N};/512_cv 1.77 % 1.77 % 10 +stringa copy{str_with_len_N};/1024_mean 16.2 ns 16.2 ns 10 +stringa copy{str_with_len_N};/1024_median 16.1 ns 16.1 ns 10 +stringa copy{str_with_len_N};/1024_stddev 0.186 ns 0.186 ns 10 +stringa copy{str_with_len_N};/1024_cv 1.15 % 1.15 % 10 +stringa copy{str_with_len_N};/2048_mean 16.2 ns 16.2 ns 10 +stringa copy{str_with_len_N};/2048_median 16.2 ns 16.2 ns 10 +stringa copy{str_with_len_N};/2048_stddev 0.171 ns 0.171 ns 10 +stringa copy{str_with_len_N};/2048_cv 1.06 % 1.06 % 10 +stringa copy{str_with_len_N};/4096_mean 16.2 ns 16.2 ns 10 +stringa copy{str_with_len_N};/4096_median 16.1 ns 16.1 ns 10 +stringa copy{str_with_len_N};/4096_stddev 0.266 ns 0.266 ns 10 +stringa copy{str_with_len_N};/4096_cv 1.64 % 1.64 % 10 +lstringa<16> copy{str_with_len_N};/15_mean 4.87 ns 4.87 ns 10 +lstringa<16> copy{str_with_len_N};/15_median 4.84 ns 4.84 ns 10 +lstringa<16> copy{str_with_len_N};/15_stddev 0.113 ns 0.113 ns 10 +lstringa<16> copy{str_with_len_N};/15_cv 2.32 % 2.32 % 10 +lstringa<16> copy{str_with_len_N};/16_mean 4.83 ns 4.83 ns 10 +lstringa<16> copy{str_with_len_N};/16_median 4.82 ns 4.82 ns 10 +lstringa<16> copy{str_with_len_N};/16_stddev 0.074 ns 0.074 ns 10 +lstringa<16> copy{str_with_len_N};/16_cv 1.54 % 1.54 % 10 +lstringa<16> copy{str_with_len_N};/23_mean 4.90 ns 4.90 ns 10 +lstringa<16> copy{str_with_len_N};/23_median 4.86 ns 4.86 ns 10 +lstringa<16> copy{str_with_len_N};/23_stddev 0.146 ns 0.146 ns 10 +lstringa<16> copy{str_with_len_N};/23_cv 2.99 % 2.99 % 10 +lstringa<16> copy{str_with_len_N};/24_mean 25.0 ns 25.0 ns 10 +lstringa<16> copy{str_with_len_N};/24_median 24.7 ns 24.7 ns 10 +lstringa<16> copy{str_with_len_N};/24_stddev 0.875 ns 0.875 ns 10 +lstringa<16> copy{str_with_len_N};/24_cv 3.50 % 3.50 % 10 +lstringa<16> copy{str_with_len_N};/32_mean 25.0 ns 25.1 ns 10 +lstringa<16> copy{str_with_len_N};/32_median 24.8 ns 24.8 ns 10 +lstringa<16> copy{str_with_len_N};/32_stddev 1.05 ns 1.05 ns 10 +lstringa<16> copy{str_with_len_N};/32_cv 4.20 % 4.20 % 10 +lstringa<16> copy{str_with_len_N};/64_mean 25.9 ns 25.9 ns 10 +lstringa<16> copy{str_with_len_N};/64_median 25.7 ns 25.7 ns 10 +lstringa<16> copy{str_with_len_N};/64_stddev 0.649 ns 0.649 ns 10 +lstringa<16> copy{str_with_len_N};/64_cv 2.51 % 2.51 % 10 +lstringa<16> copy{str_with_len_N};/128_mean 27.0 ns 27.0 ns 10 +lstringa<16> copy{str_with_len_N};/128_median 26.9 ns 26.9 ns 10 +lstringa<16> copy{str_with_len_N};/128_stddev 0.661 ns 0.661 ns 10 +lstringa<16> copy{str_with_len_N};/128_cv 2.45 % 2.45 % 10 +lstringa<16> copy{str_with_len_N};/256_mean 28.3 ns 28.3 ns 10 +lstringa<16> copy{str_with_len_N};/256_median 27.8 ns 27.8 ns 10 +lstringa<16> copy{str_with_len_N};/256_stddev 1.33 ns 1.33 ns 10 +lstringa<16> copy{str_with_len_N};/256_cv 4.70 % 4.70 % 10 +lstringa<16> copy{str_with_len_N};/512_mean 30.7 ns 30.7 ns 10 +lstringa<16> copy{str_with_len_N};/512_median 30.6 ns 30.6 ns 10 +lstringa<16> copy{str_with_len_N};/512_stddev 0.663 ns 0.663 ns 10 +lstringa<16> copy{str_with_len_N};/512_cv 2.16 % 2.16 % 10 +lstringa<16> copy{str_with_len_N};/1024_mean 83.7 ns 83.7 ns 10 +lstringa<16> copy{str_with_len_N};/1024_median 83.5 ns 83.5 ns 10 +lstringa<16> copy{str_with_len_N};/1024_stddev 4.33 ns 4.33 ns 10 +lstringa<16> copy{str_with_len_N};/1024_cv 5.17 % 5.17 % 10 +lstringa<16> copy{str_with_len_N};/2048_mean 97.7 ns 97.7 ns 10 +lstringa<16> copy{str_with_len_N};/2048_median 96.1 ns 96.1 ns 10 +lstringa<16> copy{str_with_len_N};/2048_stddev 8.19 ns 8.19 ns 10 +lstringa<16> copy{str_with_len_N};/2048_cv 8.38 % 8.38 % 10 +lstringa<16> copy{str_with_len_N};/4096_mean 116 ns 116 ns 10 +lstringa<16> copy{str_with_len_N};/4096_median 116 ns 116 ns 10 +lstringa<16> copy{str_with_len_N};/4096_stddev 5.46 ns 5.46 ns 10 +lstringa<16> copy{str_with_len_N};/4096_cv 4.71 % 4.71 % 10 +lstringa<512> copy{str_with_len_N};/15_mean 4.99 ns 4.99 ns 10 +lstringa<512> copy{str_with_len_N};/15_median 4.86 ns 4.86 ns 10 +lstringa<512> copy{str_with_len_N};/15_stddev 0.351 ns 0.351 ns 10 +lstringa<512> copy{str_with_len_N};/15_cv 7.03 % 7.03 % 10 +lstringa<512> copy{str_with_len_N};/16_mean 4.89 ns 4.89 ns 10 +lstringa<512> copy{str_with_len_N};/16_median 4.88 ns 4.88 ns 10 +lstringa<512> copy{str_with_len_N};/16_stddev 0.134 ns 0.134 ns 10 +lstringa<512> copy{str_with_len_N};/16_cv 2.73 % 2.73 % 10 +lstringa<512> copy{str_with_len_N};/23_mean 4.89 ns 4.89 ns 10 +lstringa<512> copy{str_with_len_N};/23_median 4.83 ns 4.83 ns 10 +lstringa<512> copy{str_with_len_N};/23_stddev 0.137 ns 0.137 ns 10 +lstringa<512> copy{str_with_len_N};/23_cv 2.80 % 2.80 % 10 +lstringa<512> copy{str_with_len_N};/24_mean 4.85 ns 4.85 ns 10 +lstringa<512> copy{str_with_len_N};/24_median 4.82 ns 4.82 ns 10 +lstringa<512> copy{str_with_len_N};/24_stddev 0.094 ns 0.094 ns 10 +lstringa<512> copy{str_with_len_N};/24_cv 1.94 % 1.94 % 10 +lstringa<512> copy{str_with_len_N};/32_mean 4.52 ns 4.52 ns 10 +lstringa<512> copy{str_with_len_N};/32_median 4.49 ns 4.49 ns 10 +lstringa<512> copy{str_with_len_N};/32_stddev 0.099 ns 0.099 ns 10 +lstringa<512> copy{str_with_len_N};/32_cv 2.20 % 2.20 % 10 +lstringa<512> copy{str_with_len_N};/64_mean 6.15 ns 6.15 ns 10 +lstringa<512> copy{str_with_len_N};/64_median 6.08 ns 6.08 ns 10 +lstringa<512> copy{str_with_len_N};/64_stddev 0.283 ns 0.283 ns 10 +lstringa<512> copy{str_with_len_N};/64_cv 4.61 % 4.61 % 10 +lstringa<512> copy{str_with_len_N};/128_mean 6.59 ns 6.59 ns 10 +lstringa<512> copy{str_with_len_N};/128_median 6.49 ns 6.49 ns 10 +lstringa<512> copy{str_with_len_N};/128_stddev 0.309 ns 0.309 ns 10 +lstringa<512> copy{str_with_len_N};/128_cv 4.69 % 4.69 % 10 +lstringa<512> copy{str_with_len_N};/256_mean 8.29 ns 8.29 ns 10 +lstringa<512> copy{str_with_len_N};/256_median 8.28 ns 8.28 ns 10 +lstringa<512> copy{str_with_len_N};/256_stddev 0.145 ns 0.145 ns 10 +lstringa<512> copy{str_with_len_N};/256_cv 1.75 % 1.75 % 10 +lstringa<512> copy{str_with_len_N};/512_mean 10.6 ns 10.6 ns 10 +lstringa<512> copy{str_with_len_N};/512_median 10.6 ns 10.6 ns 10 +lstringa<512> copy{str_with_len_N};/512_stddev 0.196 ns 0.196 ns 10 +lstringa<512> copy{str_with_len_N};/512_cv 1.84 % 1.84 % 10 +lstringa<512> copy{str_with_len_N};/1024_mean 89.0 ns 89.0 ns 10 +lstringa<512> copy{str_with_len_N};/1024_median 89.5 ns 89.5 ns 10 +lstringa<512> copy{str_with_len_N};/1024_stddev 4.99 ns 4.99 ns 10 +lstringa<512> copy{str_with_len_N};/1024_cv 5.60 % 5.60 % 10 +lstringa<512> copy{str_with_len_N};/2048_mean 101 ns 101 ns 10 +lstringa<512> copy{str_with_len_N};/2048_median 99.8 ns 99.8 ns 10 +lstringa<512> copy{str_with_len_N};/2048_stddev 7.23 ns 7.23 ns 10 +lstringa<512> copy{str_with_len_N};/2048_cv 7.15 % 7.15 % 10 +lstringa<512> copy{str_with_len_N};/4096_mean 115 ns 115 ns 10 +lstringa<512> copy{str_with_len_N};/4096_median 114 ns 114 ns 10 +lstringa<512> copy{str_with_len_N};/4096_stddev 4.47 ns 4.47 ns 10 +lstringa<512> copy{str_with_len_N};/4096_cv 3.89 % 3.89 % 10 +----- Convert to int '1234567' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_mean 27.3 ns 27.3 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_median 26.8 ns 26.8 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_stddev 1.08 ns 1.08 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_cv 3.97 % 3.97 % 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_mean 12.4 ns 12.4 ns 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_median 12.3 ns 12.3 ns 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_stddev 0.287 ns 0.287 ns 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_cv 2.32 % 2.32 % 10 +stringa s = "123456789"; int res = s.to_int_mean 7.92 ns 7.92 ns 10 +stringa s = "123456789"; int res = s.to_int_median 7.90 ns 7.90 ns 10 +stringa s = "123456789"; int res = s.to_int_stddev 0.170 ns 0.170 ns 10 +stringa s = "123456789"; int res = s.to_int_cv 2.15 % 2.15 % 10 +ssa s = "123456789"; int res = s.to_int_mean 7.73 ns 7.73 ns 10 +ssa s = "123456789"; int res = s.to_int_median 7.70 ns 7.70 ns 10 +ssa s = "123456789"; int res = s.to_int_stddev 0.126 ns 0.126 ns 10 +ssa s = "123456789"; int res = s.to_int_cv 1.63 % 1.63 % 10 +lstringa<20> s = "123456789"; int res = s.to_int_mean 7.73 ns 7.73 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_median 7.60 ns 7.60 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_stddev 0.343 ns 0.343 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_cv 4.43 % 4.43 % 10 +----- Convert to unsigned 'abcDef' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_mean 24.0 ns 24.0 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_median 23.9 ns 23.9 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_stddev 0.391 ns 0.391 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_cv 1.63 % 1.63 % 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_mean 14.8 ns 14.8 ns 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_median 14.7 ns 14.7 ns 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_stddev 0.433 ns 0.433 ns 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_cv 2.93 % 2.93 % 10 +stringa s = "abcDef"; int res = s.to_int_mean 7.55 ns 7.55 ns 10 +stringa s = "abcDef"; int res = s.to_int_median 7.48 ns 7.48 ns 10 +stringa s = "abcDef"; int res = s.to_int_stddev 0.242 ns 0.242 ns 10 +stringa s = "abcDef"; int res = s.to_int_cv 3.20 % 3.20 % 10 +ssa s = "abcDef"; int res = s.to_int_mean 8.28 ns 8.28 ns 10 +ssa s = "abcDef"; int res = s.to_int_median 8.20 ns 8.20 ns 10 +ssa s = "abcDef"; int res = s.to_int_stddev 0.205 ns 0.205 ns 10 +ssa s = "abcDef"; int res = s.to_int_cv 2.48 % 2.48 % 10 +lstringa<20> s = "abcDef"; int res = s.to_int_mean 8.16 ns 8.16 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_median 8.11 ns 8.11 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_stddev 0.113 ns 0.113 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_cv 1.39 % 1.39 % 10 +----- Convert to int ' 1234567' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_mean 29.1 ns 29.1 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_median 29.6 ns 29.6 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_stddev 0.966 ns 0.966 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_cv 3.32 % 3.32 % 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_mean 16.7 ns 16.7 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_median 16.8 ns 16.8 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_stddev 0.714 ns 0.714 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_cv 4.27 % 4.27 % 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_mean 14.6 ns 14.6 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_median 14.6 ns 14.6 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_stddev 0.378 ns 0.378 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_cv 2.59 % 2.59 % 10 +-- Append const literal of 16 bytes 64 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << "abbaabbaabbaabba";_mean 1439 ns 1439 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_median 1423 ns 1423 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_stddev 55.7 ns 55.7 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_cv 3.87 % 3.87 % 10 +std::string str; ... str += "abbaabbaabbaabba";_mean 369 ns 369 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_median 366 ns 366 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_stddev 13.1 ns 13.1 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_cv 3.56 % 3.56 % 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_mean 372 ns 372 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_median 366 ns 366 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_stddev 17.5 ns 17.5 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_cv 4.69 % 4.69 % 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_mean 258 ns 258 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_median 255 ns 255 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_stddev 10.4 ns 10.4 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_cv 4.02 % 4.02 % 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_mean 241 ns 241 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_median 237 ns 237 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_stddev 9.51 ns 9.51 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_cv 3.96 % 3.96 % 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_mean 140 ns 140 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_median 139 ns 139 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_stddev 1.89 ns 1.89 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_cv 1.35 % 1.35 % 10 +-- Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_mean 1399 ns 1399 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_median 1392 ns 1392 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_stddev 21.4 ns 21.4 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_cv 1.53 % 1.53 % 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_mean 1343 ns 1343 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_median 1335 ns 1335 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_stddev 29.7 ns 29.7 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_cv 2.22 % 2.22 % 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_mean 429 ns 429 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_median 425 ns 425 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_stddev 11.9 ns 11.9 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_cv 2.78 % 2.78 % 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_mean 361 ns 361 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_median 362 ns 362 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_stddev 11.1 ns 11.1 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_cv 3.07 % 3.07 % 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_mean 316 ns 316 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_median 316 ns 316 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_stddev 10.4 ns 10.4 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_cv 3.28 % 3.28 % 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_mean 256 ns 256 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_median 254 ns 254 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_stddev 7.09 ns 7.09 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_cv 2.77 % 2.77 % 10 +-- Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_mean 74700 ns 74701 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_median 74616 ns 74616 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_stddev 1876 ns 1876 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_cv 2.51 % 2.51 % 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 72474 ns 72474 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 71002 ns 71002 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 3104 ns 3104 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 4.28 % 4.28 % 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 19642 ns 19642 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 19294 ns 19294 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 924 ns 924 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 4.70 % 4.70 % 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 17774 ns 17774 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 17626 ns 17626 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 440 ns 440 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 2.48 % 2.48 % 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 17565 ns 17565 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 17594 ns 17594 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 482 ns 482 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 2.75 % 2.75 % 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 18274 ns 18274 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 18226 ns 18226 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 365 ns 365 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 2.00 % 2.00 % 10 +-- Append 2 string of 16 bytes 32 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var1 << str_var2;_mean 1400 ns 1400 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_median 1371 ns 1371 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_stddev 59.5 ns 59.5 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_cv 4.25 % 4.25 % 10 +std::string str; ... str += str_var1 + str_var2;_mean 1342 ns 1342 ns 10 +std::string str; ... str += str_var1 + str_var2;_median 1329 ns 1329 ns 10 +std::string str; ... str += str_var1 + str_var2;_stddev 40.1 ns 40.1 ns 10 +std::string str; ... str += str_var1 + str_var2;_cv 2.99 % 2.99 % 10 +lstringa<16> str; ... str += str_var1 + str_var2;_mean 598 ns 598 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_median 591 ns 591 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_stddev 32.2 ns 32.2 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_cv 5.39 % 5.39 % 10 +lstringa<128> str; ... str += str_var1 + str_var2;_mean 500 ns 500 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_median 496 ns 496 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_stddev 13.1 ns 13.1 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_cv 2.61 % 2.61 % 10 +lstringa<512> str; ... str += str_var1 + str_var2;_mean 462 ns 462 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_median 462 ns 462 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_stddev 20.4 ns 20.4 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_cv 4.42 % 4.42 % 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_mean 431 ns 431 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_median 440 ns 440 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_stddev 31.5 ns 31.5 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_cv 7.31 % 7.31 % 10 +-- Append text, number, text --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; str << "test = " << k << " times";_mean 3419 ns 3419 ns 10 +std::stringstream str; str << "test = " << k << " times";_median 3299 ns 3299 ns 10 +std::stringstream str; str << "test = " << k << " times";_stddev 235 ns 235 ns 10 +std::stringstream str; str << "test = " << k << " times";_cv 6.87 % 6.87 % 10 +std::string str = "test = " + std::to_string(k) + " times";_mean 451 ns 451 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_median 451 ns 451 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_stddev 4.99 ns 4.99 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_cv 1.11 % 1.11 % 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_mean 1509 ns 1509 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_median 1515 ns 1515 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_stddev 26.5 ns 26.5 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_cv 1.75 % 1.75 % 10 +std::string str = std::format("test = {} times", k);_mean 1286 ns 1286 ns 10 +std::string str = std::format("test = {} times", k);_median 1278 ns 1278 ns 10 +std::string str = std::format("test = {} times", k);_stddev 30.8 ns 30.8 ns 10 +std::string str = std::format("test = {} times", k);_cv 2.40 % 2.40 % 10 +lstringa<8> str; str.format("test = {} times", k);_mean 1618 ns 1618 ns 10 +lstringa<8> str; str.format("test = {} times", k);_median 1609 ns 1609 ns 10 +lstringa<8> str; str.format("test = {} times", k);_stddev 21.9 ns 21.9 ns 10 +lstringa<8> str; str.format("test = {} times", k);_cv 1.35 % 1.35 % 10 +lstringa<32> str; str.format("test = {} times", k);_mean 1132 ns 1132 ns 10 +lstringa<32> str; str.format("test = {} times", k);_median 1127 ns 1127 ns 10 +lstringa<32> str; str.format("test = {} times", k);_stddev 33.3 ns 33.3 ns 10 +lstringa<32> str; str.format("test = {} times", k);_cv 2.94 % 2.94 % 10 +lstringa<8> str = "test = " + k + " times";_mean 316 ns 316 ns 10 +lstringa<8> str = "test = " + k + " times";_median 316 ns 316 ns 10 +lstringa<8> str = "test = " + k + " times";_stddev 4.81 ns 4.81 ns 10 +lstringa<8> str = "test = " + k + " times";_cv 1.52 % 1.52 % 10 +lstringa<32> str = "test = " + k + " times";_mean 162 ns 162 ns 10 +lstringa<32> str = "test = " + k + " times";_median 160 ns 160 ns 10 +lstringa<32> str = "test = " + k + " times";_stddev 6.29 ns 6.29 ns 10 +lstringa<32> str = "test = " + k + " times";_cv 3.88 % 3.88 % 10 +stringa str = "test = " + k + " times";_mean 174 ns 174 ns 10 +stringa str = "test = " + k + " times";_median 173 ns 173 ns 10 +stringa str = "test = " + k + " times";_stddev 3.60 ns 3.60 ns 10 +stringa str = "test = " + k + " times";_cv 2.07 % 2.07 % 10 +-- Split text and convert to int --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string::find + substr + std::strtol_mean 285 ns 285 ns 10 +std::string::find + substr + std::strtol_median 282 ns 282 ns 10 +std::string::find + substr + std::strtol_stddev 11.1 ns 11.1 ns 10 +std::string::find + substr + std::strtol_cv 3.90 % 3.90 % 10 +ssa::splitter + ssa::as_int_mean 139 ns 139 ns 10 +ssa::splitter + ssa::as_int_median 139 ns 139 ns 10 +ssa::splitter + ssa::as_int_stddev 1.89 ns 1.89 ns 10 +ssa::splitter + ssa::as_int_cv 1.36 % 1.37 % 10 +ssa::splitf + functor_mean 153 ns 153 ns 10 +ssa::splitf + functor_median 152 ns 152 ns 10 +ssa::splitf + functor_stddev 1.34 ns 1.34 ns 10 +ssa::splitf + functor_cv 0.88 % 0.88 % 10 +-- Replace symbols in text ~400 symbols --/repeats:1 0.000 ns 0.000 ns 1000000000 +Naive (and wrong) replace symbols with std::string find + replace_mean 867 ns 867 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_median 866 ns 866 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_stddev 9.68 ns 9.68 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_cv 1.12 % 1.12 % 10 +replace symbols with std::string find_first_of + replace_mean 2597 ns 2597 ns 10 +replace symbols with std::string find_first_of + replace_median 2577 ns 2577 ns 10 +replace symbols with std::string find_first_of + replace_stddev 74.4 ns 74.4 ns 10 +replace symbols with std::string find_first_of + replace_cv 2.86 % 2.86 % 10 +replace symbols with std::string_view find_first_of + copy_mean 2671 ns 2671 ns 10 +replace symbols with std::string_view find_first_of + copy_median 2667 ns 2667 ns 10 +replace symbols with std::string_view find_first_of + copy_stddev 54.9 ns 54.9 ns 10 +replace symbols with std::string_view find_first_of + copy_cv 2.05 % 2.05 % 10 +replace runtime symbols with string expressions and without remembering all search results_mean 1543 ns 1543 ns 10 +replace runtime symbols with string expressions and without remembering all search results_median 1549 ns 1549 ns 10 +replace runtime symbols with string expressions and without remembering all search results_stddev 22.7 ns 22.7 ns 10 +replace runtime symbols with string expressions and without remembering all search results_cv 1.47 % 1.47 % 10 +replace runtime symbols with simstr and memorization of all search results_mean 1181 ns 1181 ns 10 +replace runtime symbols with simstr and memorization of all search results_median 1178 ns 1178 ns 10 +replace runtime symbols with simstr and memorization of all search results_stddev 42.8 ns 42.8 ns 10 +replace runtime symbols with simstr and memorization of all search results_cv 3.63 % 3.62 % 10 +replace const symbols with string expressions and without remembering all search results_mean 1265 ns 1265 ns 10 +replace const symbols with string expressions and without remembering all search results_median 1255 ns 1255 ns 10 +replace const symbols with string expressions and without remembering all search results_stddev 18.4 ns 18.4 ns 10 +replace const symbols with string expressions and without remembering all search results_cv 1.45 % 1.45 % 10 +replace const symbols with string expressions and memorization of all search results_mean 866 ns 866 ns 10 +replace const symbols with string expressions and memorization of all search results_median 858 ns 858 ns 10 +replace const symbols with string expressions and memorization of all search results_stddev 16.6 ns 16.6 ns 10 +replace const symbols with string expressions and memorization of all search results_cv 1.91 % 1.91 % 10 +-- Replace symbols in text ~40 symbols --/repeats:1 0.000 ns 0.000 ns 1000000000 +Short Naive (and wrong) replace symbols with std::string find + replace_mean 170 ns 170 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_median 165 ns 165 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_stddev 13.1 ns 13.1 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_cv 7.73 % 7.73 % 10 +Short replace symbols with std::string find_first_of + replace_mean 348 ns 348 ns 10 +Short replace symbols with std::string find_first_of + replace_median 332 ns 332 ns 10 +Short replace symbols with std::string find_first_of + replace_stddev 35.6 ns 35.6 ns 10 +Short replace symbols with std::string find_first_of + replace_cv 10.24 % 10.24 % 10 +Short replace symbols with std::string_view find_first_of + copy_mean 322 ns 322 ns 10 +Short replace symbols with std::string_view find_first_of + copy_median 321 ns 321 ns 10 +Short replace symbols with std::string_view find_first_of + copy_stddev 6.90 ns 6.90 ns 10 +Short replace symbols with std::string_view find_first_of + copy_cv 2.14 % 2.14 % 10 +Short replace runtime symbols with string expressions and without remembering all search results_mean 198 ns 198 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_median 198 ns 198 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_stddev 3.57 ns 3.57 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_cv 1.81 % 1.81 % 10 +Short replace runtime symbols with simstr and memorization of all search results_mean 192 ns 192 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_median 192 ns 192 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_stddev 4.04 ns 4.04 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_cv 2.10 % 2.10 % 10 +Short replace const symbols with string expressions and without remembering all search results_mean 165 ns 165 ns 10 +Short replace const symbols with string expressions and without remembering all search results_median 165 ns 165 ns 10 +Short replace const symbols with string expressions and without remembering all search results_stddev 3.56 ns 3.56 ns 10 +Short replace const symbols with string expressions and without remembering all search results_cv 2.17 % 2.17 % 10 +Short replace const symbols with string expressions and memorization of all search results_mean 153 ns 153 ns 10 +Short replace const symbols with string expressions and memorization of all search results_median 153 ns 153 ns 10 +Short replace const symbols with string expressions and memorization of all search results_stddev 2.48 ns 2.48 ns 10 +Short replace const symbols with string expressions and memorization of all search results_cv 1.62 % 1.62 % 10 +----- Replace All Str To Longer Size ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +replace bb to ---- in std::string|64_mean 162 ns 162 ns 10 +replace bb to ---- in std::string|64_median 163 ns 163 ns 10 +replace bb to ---- in std::string|64_stddev 4.04 ns 4.04 ns 10 +replace bb to ---- in std::string|64_cv 2.49 % 2.49 % 10 +replace bb to ---- in std::string|256_mean 493 ns 493 ns 10 +replace bb to ---- in std::string|256_median 493 ns 493 ns 10 +replace bb to ---- in std::string|256_stddev 8.37 ns 8.37 ns 10 +replace bb to ---- in std::string|256_cv 1.70 % 1.70 % 10 +replace bb to ---- in std::string|512_mean 993 ns 993 ns 10 +replace bb to ---- in std::string|512_median 994 ns 994 ns 10 +replace bb to ---- in std::string|512_stddev 14.5 ns 14.5 ns 10 +replace bb to ---- in std::string|512_cv 1.46 % 1.46 % 10 +replace bb to ---- in std::string|1024_mean 2333 ns 2333 ns 10 +replace bb to ---- in std::string|1024_median 2320 ns 2320 ns 10 +replace bb to ---- in std::string|1024_stddev 65.6 ns 65.6 ns 10 +replace bb to ---- in std::string|1024_cv 2.81 % 2.81 % 10 +replace bb to ---- in std::string|2048_mean 6359 ns 6359 ns 10 +replace bb to ---- in std::string|2048_median 6499 ns 6499 ns 10 +replace bb to ---- in std::string|2048_stddev 455 ns 455 ns 10 +replace bb to ---- in std::string|2048_cv 7.16 % 7.16 % 10 +replace bb to ---- in lstringa<8>|64_mean 167 ns 167 ns 10 +replace bb to ---- in lstringa<8>|64_median 167 ns 167 ns 10 +replace bb to ---- in lstringa<8>|64_stddev 3.62 ns 3.62 ns 10 +replace bb to ---- in lstringa<8>|64_cv 2.17 % 2.17 % 10 +replace bb to ---- in lstringa<8>|256_mean 495 ns 495 ns 10 +replace bb to ---- in lstringa<8>|256_median 492 ns 492 ns 10 +replace bb to ---- in lstringa<8>|256_stddev 10.9 ns 10.9 ns 10 +replace bb to ---- in lstringa<8>|256_cv 2.20 % 2.20 % 10 +replace bb to ---- in lstringa<8>|512_mean 922 ns 922 ns 10 +replace bb to ---- in lstringa<8>|512_median 922 ns 922 ns 10 +replace bb to ---- in lstringa<8>|512_stddev 23.3 ns 23.3 ns 10 +replace bb to ---- in lstringa<8>|512_cv 2.53 % 2.53 % 10 +replace bb to ---- in lstringa<8>|1024_mean 1862 ns 1862 ns 10 +replace bb to ---- in lstringa<8>|1024_median 1861 ns 1861 ns 10 +replace bb to ---- in lstringa<8>|1024_stddev 30.7 ns 30.7 ns 10 +replace bb to ---- in lstringa<8>|1024_cv 1.65 % 1.65 % 10 +replace bb to ---- in lstringa<8>|2048_mean 3551 ns 3551 ns 10 +replace bb to ---- in lstringa<8>|2048_median 3539 ns 3539 ns 10 +replace bb to ---- in lstringa<8>|2048_stddev 62.8 ns 62.8 ns 10 +replace bb to ---- in lstringa<8>|2048_cv 1.77 % 1.77 % 10 +replace bb to ---- by init stringa|64_mean 121 ns 121 ns 10 +replace bb to ---- by init stringa|64_median 122 ns 122 ns 10 +replace bb to ---- by init stringa|64_stddev 2.81 ns 2.81 ns 10 +replace bb to ---- by init stringa|64_cv 2.31 % 2.31 % 10 +replace bb to ---- by init stringa|256_mean 444 ns 444 ns 10 +replace bb to ---- by init stringa|256_median 444 ns 444 ns 10 +replace bb to ---- by init stringa|256_stddev 6.27 ns 6.27 ns 10 +replace bb to ---- by init stringa|256_cv 1.41 % 1.41 % 10 +replace bb to ---- by init stringa|512_mean 827 ns 827 ns 10 +replace bb to ---- by init stringa|512_median 825 ns 825 ns 10 +replace bb to ---- by init stringa|512_stddev 15.8 ns 15.8 ns 10 +replace bb to ---- by init stringa|512_cv 1.91 % 1.91 % 10 +replace bb to ---- by init stringa|1024_mean 1637 ns 1637 ns 10 +replace bb to ---- by init stringa|1024_median 1635 ns 1635 ns 10 +replace bb to ---- by init stringa|1024_stddev 22.9 ns 22.9 ns 10 +replace bb to ---- by init stringa|1024_cv 1.40 % 1.40 % 10 +replace bb to ---- by init stringa|2048_mean 3280 ns 3280 ns 10 +replace bb to ---- by init stringa|2048_median 3267 ns 3267 ns 10 +replace bb to ---- by init stringa|2048_stddev 71.3 ns 71.3 ns 10 +replace bb to ---- by init stringa|2048_cv 2.17 % 2.17 % 10 +----- Replace All Str To Same Size ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +replace bb to -- in std::string|64_mean 125 ns 125 ns 10 +replace bb to -- in std::string|64_median 125 ns 125 ns 10 +replace bb to -- in std::string|64_stddev 2.16 ns 2.16 ns 10 +replace bb to -- in std::string|64_cv 1.73 % 1.73 % 10 +replace bb to -- in std::string|256_mean 405 ns 405 ns 10 +replace bb to -- in std::string|256_median 402 ns 402 ns 10 +replace bb to -- in std::string|256_stddev 8.63 ns 8.63 ns 10 +replace bb to -- in std::string|256_cv 2.13 % 2.13 % 10 +replace bb to -- in std::string|512_mean 780 ns 780 ns 10 +replace bb to -- in std::string|512_median 777 ns 777 ns 10 +replace bb to -- in std::string|512_stddev 13.5 ns 13.5 ns 10 +replace bb to -- in std::string|512_cv 1.73 % 1.73 % 10 +replace bb to -- in std::string|1024_mean 1446 ns 1446 ns 10 +replace bb to -- in std::string|1024_median 1452 ns 1452 ns 10 +replace bb to -- in std::string|1024_stddev 23.9 ns 23.9 ns 10 +replace bb to -- in std::string|1024_cv 1.65 % 1.65 % 10 +replace bb to -- in std::string|2048_mean 3138 ns 3138 ns 10 +replace bb to -- in std::string|2048_median 3133 ns 3133 ns 10 +replace bb to -- in std::string|2048_stddev 68.1 ns 68.1 ns 10 +replace bb to -- in std::string|2048_cv 2.17 % 2.17 % 10 +replace bb to -- in lstringa<8>|64_mean 103 ns 103 ns 10 +replace bb to -- in lstringa<8>|64_median 103 ns 103 ns 10 +replace bb to -- in lstringa<8>|64_stddev 3.47 ns 3.47 ns 10 +replace bb to -- in lstringa<8>|64_cv 3.35 % 3.35 % 10 +replace bb to -- in lstringa<8>|256_mean 301 ns 301 ns 10 +replace bb to -- in lstringa<8>|256_median 300 ns 300 ns 10 +replace bb to -- in lstringa<8>|256_stddev 4.94 ns 4.94 ns 10 +replace bb to -- in lstringa<8>|256_cv 1.64 % 1.64 % 10 +replace bb to -- in lstringa<8>|512_mean 548 ns 548 ns 10 +replace bb to -- in lstringa<8>|512_median 549 ns 549 ns 10 +replace bb to -- in lstringa<8>|512_stddev 11.5 ns 11.5 ns 10 +replace bb to -- in lstringa<8>|512_cv 2.10 % 2.10 % 10 +replace bb to -- in lstringa<8>|1024_mean 1112 ns 1112 ns 10 +replace bb to -- in lstringa<8>|1024_median 1117 ns 1117 ns 10 +replace bb to -- in lstringa<8>|1024_stddev 21.9 ns 21.9 ns 10 +replace bb to -- in lstringa<8>|1024_cv 1.97 % 1.97 % 10 +replace bb to -- in lstringa<8>|2048_mean 2105 ns 2105 ns 10 +replace bb to -- in lstringa<8>|2048_median 2088 ns 2088 ns 10 +replace bb to -- in lstringa<8>|2048_stddev 58.9 ns 58.9 ns 10 +replace bb to -- in lstringa<8>|2048_cv 2.80 % 2.80 % 10 +replace bb to -- by init stringa|64_mean 91.4 ns 91.4 ns 10 +replace bb to -- by init stringa|64_median 91.0 ns 91.0 ns 10 +replace bb to -- by init stringa|64_stddev 1.74 ns 1.74 ns 10 +replace bb to -- by init stringa|64_cv 1.90 % 1.90 % 10 +replace bb to -- by init stringa|256_mean 261 ns 261 ns 10 +replace bb to -- by init stringa|256_median 258 ns 258 ns 10 +replace bb to -- by init stringa|256_stddev 7.95 ns 7.95 ns 10 +replace bb to -- by init stringa|256_cv 3.05 % 3.05 % 10 +replace bb to -- by init stringa|512_mean 485 ns 485 ns 10 +replace bb to -- by init stringa|512_median 485 ns 485 ns 10 +replace bb to -- by init stringa|512_stddev 6.01 ns 6.01 ns 10 +replace bb to -- by init stringa|512_cv 1.24 % 1.24 % 10 +replace bb to -- by init stringa|1024_mean 984 ns 984 ns 10 +replace bb to -- by init stringa|1024_median 976 ns 976 ns 10 +replace bb to -- by init stringa|1024_stddev 31.5 ns 31.5 ns 10 +replace bb to -- by init stringa|1024_cv 3.20 % 3.20 % 10 +replace bb to -- by init stringa|2048_mean 1862 ns 1862 ns 10 +replace bb to -- by init stringa|2048_median 1872 ns 1872 ns 10 +replace bb to -- by init stringa|2048_stddev 35.5 ns 35.5 ns 10 +replace bb to -- by init stringa|2048_cv 1.91 % 1.91 % 10 +----- Hash Map insert and find ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +hashStrMapA emplace & find stringa;_mean 3769704 ns 3769718 ns 10 +hashStrMapA emplace & find stringa;_median 3760472 ns 3760485 ns 10 +hashStrMapA emplace & find stringa;_stddev 60750 ns 60751 ns 10 +hashStrMapA emplace & find stringa;_cv 1.61 % 1.61 % 10 +std::unordered_map emplace & find std::string;_mean 3652417 ns 3652436 ns 10 +std::unordered_map emplace & find std::string;_median 3645060 ns 3645073 ns 10 +std::unordered_map emplace & find std::string;_stddev 82821 ns 82811 ns 10 +std::unordered_map emplace & find std::string;_cv 2.27 % 2.27 % 10 +hashStrMapA emplace & find ssa;_mean 3800957 ns 3800973 ns 10 +hashStrMapA emplace & find ssa;_median 3796589 ns 3796604 ns 10 +hashStrMapA emplace & find ssa;_stddev 47150 ns 47150 ns 10 +hashStrMapA emplace & find ssa;_cv 1.24 % 1.24 % 10 +std::unordered_map emplace & find std::string_view;_mean 4103196 ns 4103210 ns 10 +std::unordered_map emplace & find std::string_view;_median 4108227 ns 4108241 ns 10 +std::unordered_map emplace & find std::string_view;_stddev 68621 ns 68620 ns 10 +std::unordered_map emplace & find std::string_view;_cv 1.67 % 1.67 % 10 +----- Build Full Func Name ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +Build func full name std::string;_mean 949 ns 949 ns 10 +Build func full name std::string;_median 945 ns 945 ns 10 +Build func full name std::string;_stddev 33.5 ns 33.5 ns 10 +Build func full name std::string;_cv 3.53 % 3.53 % 10 +Build func full name std::string 1;_mean 1025 ns 1025 ns 10 +Build func full name std::string 1;_median 1017 ns 1017 ns 10 +Build func full name std::string 1;_stddev 35.7 ns 35.7 ns 10 +Build func full name std::string 1;_cv 3.48 % 3.48 % 10 +Build func full name std::stream;_mean 2654 ns 2654 ns 10 +Build func full name std::stream;_median 2648 ns 2648 ns 10 +Build func full name std::stream;_stddev 33.0 ns 33.0 ns 10 +Build func full name std::stream;_cv 1.24 % 1.24 % 10 +Build func full name stringa;_mean 500 ns 500 ns 10 +Build func full name stringa;_median 494 ns 494 ns 10 +Build func full name stringa;_stddev 16.0 ns 16.0 ns 10 +Build func full name stringa;_cv 3.20 % 3.20 % 10 +Build func full name stringa 1;_mean 716 ns 716 ns 10 +Build func full name stringa 1;_median 712 ns 712 ns 10 +Build func full name stringa 1;_stddev 20.9 ns 20.9 ns 10 +Build func full name stringa 1;_cv 2.92 % 2.92 % 10 diff --git a/bench/results/002-Xeon E5-2682 v4, Windows 10, Clang-19.txt b/bench/results/002-Xeon E5-2682 v4, Windows 10, Clang-19.txt new file mode 100644 index 0000000..b97107a --- /dev/null +++ b/bench/results/002-Xeon E5-2682 v4, Windows 10, Clang-19.txt @@ -0,0 +1,777 @@ +2025-08-06T12:08:34+03:00 +Running benchStr.exe +Run on (32 X 2518.87 MHz CPU s) +CPU Caches: + L1 Data 32 KiB (x16) + L1 Instruction 32 KiB (x16) + L2 Unified 256 KiB (x16) + L3 Unified 40960 KiB (x1) +-------------------------------------------------------------------------------------------------------------------------------------------------------- +Benchmark Time CPU Iterations +-------------------------------------------------------------------------------------------------------------------------------------------------------- +----- Create Empty Str ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e;_mean 1.12 ns 1.11 ns 10 +std::string e;_median 1.12 ns 1.11 ns 10 +std::string e;_stddev 0.025 ns 0.033 ns 10 +std::string e;_cv 2.24 % 2.98 % 10 +std::string_view e;_mean 0.377 ns 0.373 ns 10 +std::string_view e;_median 0.376 ns 0.375 ns 10 +std::string_view e;_stddev 0.021 ns 0.025 ns 10 +std::string_view e;_cv 5.58 % 6.67 % 10 +ssa e;_mean 0.367 ns 0.364 ns 10 +ssa e;_median 0.367 ns 0.359 ns 10 +ssa e;_stddev 0.007 ns 0.015 ns 10 +ssa e;_cv 1.83 % 4.07 % 10 +stringa e;_mean 0.751 ns 0.748 ns 10 +stringa e;_median 0.747 ns 0.750 ns 10 +stringa e;_stddev 0.018 ns 0.019 ns 10 +stringa e;_cv 2.43 % 2.50 % 10 +lstringa<20> e;_mean 1.14 ns 1.13 ns 10 +lstringa<20> e;_median 1.14 ns 1.12 ns 10 +lstringa<20> e;_stddev 0.022 ns 0.018 ns 10 +lstringa<20> e;_cv 1.96 % 1.60 % 10 +lstringa<40> e;_mean 1.15 ns 1.13 ns 10 +lstringa<40> e;_median 1.12 ns 1.12 ns 10 +lstringa<40> e;_stddev 0.047 ns 0.044 ns 10 +lstringa<40> e;_cv 4.14 % 3.90 % 10 +----- Create Str from short literal (9 symbols) --------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "Test text";_mean 1.85 ns 1.84 ns 10 +std::string e = "Test text";_median 1.85 ns 1.84 ns 10 +std::string e = "Test text";_stddev 0.025 ns 0.037 ns 10 +std::string e = "Test text";_cv 1.37 % 1.99 % 10 +std::string_view e = "Test text";_mean 0.740 ns 0.736 ns 10 +std::string_view e = "Test text";_median 0.740 ns 0.734 ns 10 +std::string_view e = "Test text";_stddev 0.012 ns 0.012 ns 10 +std::string_view e = "Test text";_cv 1.61 % 1.57 % 10 +ssa e = "Test text";_mean 0.371 ns 0.369 ns 10 +ssa e = "Test text";_median 0.370 ns 0.375 ns 10 +ssa e = "Test text";_stddev 0.006 ns 0.015 ns 10 +ssa e = "Test text";_cv 1.67 % 4.09 % 10 +stringa e = "Test text";_mean 1.12 ns 1.11 ns 10 +stringa e = "Test text";_median 1.12 ns 1.11 ns 10 +stringa e = "Test text";_stddev 0.028 ns 0.028 ns 10 +stringa e = "Test text";_cv 2.47 % 2.56 % 10 +lstringa<20> e = "Test text";_mean 1.84 ns 1.84 ns 10 +lstringa<20> e = "Test text";_median 1.85 ns 1.84 ns 10 +lstringa<20> e = "Test text";_stddev 0.022 ns 0.042 ns 10 +lstringa<20> e = "Test text";_cv 1.21 % 2.27 % 10 +lstringa<40> e = "Test text";_mean 1.87 ns 1.85 ns 10 +lstringa<40> e = "Test text";_median 1.87 ns 1.84 ns 10 +lstringa<40> e = "Test text";_stddev 0.035 ns 0.026 ns 10 +lstringa<40> e = "Test text";_cv 1.88 % 1.43 % 10 +----- Create Str from long literal (30 symbols) ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "123456789012345678901234567890";_mean 78.0 ns 76.6 ns 10 +std::string e = "123456789012345678901234567890";_median 78.2 ns 76.4 ns 10 +std::string e = "123456789012345678901234567890";_stddev 2.16 ns 2.02 ns 10 +std::string e = "123456789012345678901234567890";_cv 2.77 % 2.64 % 10 +std::string_view e = "123456789012345678901234567890";_mean 0.739 ns 0.731 ns 10 +std::string_view e = "123456789012345678901234567890";_median 0.736 ns 0.732 ns 10 +std::string_view e = "123456789012345678901234567890";_stddev 0.010 ns 0.017 ns 10 +std::string_view e = "123456789012345678901234567890";_cv 1.40 % 2.37 % 10 +ssa e = "123456789012345678901234567890";_mean 0.369 ns 0.370 ns 10 +ssa e = "123456789012345678901234567890";_median 0.368 ns 0.375 ns 10 +ssa e = "123456789012345678901234567890";_stddev 0.007 ns 0.011 ns 10 +ssa e = "123456789012345678901234567890";_cv 1.79 % 2.85 % 10 +stringa e = "123456789012345678901234567890";_mean 1.11 ns 1.10 ns 10 +stringa e = "123456789012345678901234567890";_median 1.11 ns 1.12 ns 10 +stringa e = "123456789012345678901234567890";_stddev 0.014 ns 0.030 ns 10 +stringa e = "123456789012345678901234567890";_cv 1.30 % 2.71 % 10 +lstringa<20> e = "123456789012345678901234567890";_mean 82.0 ns 80.7 ns 10 +lstringa<20> e = "123456789012345678901234567890";_median 81.1 ns 79.3 ns 10 +lstringa<20> e = "123456789012345678901234567890";_stddev 2.75 ns 3.08 ns 10 +lstringa<20> e = "123456789012345678901234567890";_cv 3.35 % 3.82 % 10 +lstringa<40> e = "123456789012345678901234567890";_mean 1.85 ns 1.84 ns 10 +lstringa<40> e = "123456789012345678901234567890";_median 1.85 ns 1.86 ns 10 +lstringa<40> e = "123456789012345678901234567890";_stddev 0.024 ns 0.049 ns 10 +lstringa<40> e = "123456789012345678901234567890";_cv 1.30 % 2.67 % 10 +----- Create copy of Str with 9 symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "Test text"; auto c{e};_mean 1.87 ns 1.86 ns 10 +std::string e = "Test text"; auto c{e};_median 1.86 ns 1.86 ns 10 +std::string e = "Test text"; auto c{e};_stddev 0.038 ns 0.036 ns 10 +std::string e = "Test text"; auto c{e};_cv 2.05 % 1.91 % 10 +std::string_view e = "Test text"; auto c{e};_mean 0.376 ns 0.377 ns 10 +std::string_view e = "Test text"; auto c{e};_median 0.374 ns 0.375 ns 10 +std::string_view e = "Test text"; auto c{e};_stddev 0.012 ns 0.012 ns 10 +std::string_view e = "Test text"; auto c{e};_cv 3.19 % 3.06 % 10 +ssa e = "Test text"; auto c{e};_mean 0.377 ns 0.378 ns 10 +ssa e = "Test text"; auto c{e};_median 0.375 ns 0.375 ns 10 +ssa e = "Test text"; auto c{e};_stddev 0.014 ns 0.014 ns 10 +ssa e = "Test text"; auto c{e};_cv 3.68 % 3.80 % 10 +stringa e = "Test text"; auto c{e};_mean 1.32 ns 1.32 ns 10 +stringa e = "Test text"; auto c{e};_median 1.32 ns 1.31 ns 10 +stringa e = "Test text"; auto c{e};_stddev 0.024 ns 0.022 ns 10 +stringa e = "Test text"; auto c{e};_cv 1.78 % 1.67 % 10 +lstringa<20> e = "Test text"; auto c{e};_mean 5.23 ns 5.20 ns 10 +lstringa<20> e = "Test text"; auto c{e};_median 5.23 ns 5.16 ns 10 +lstringa<20> e = "Test text"; auto c{e};_stddev 0.058 ns 0.105 ns 10 +lstringa<20> e = "Test text"; auto c{e};_cv 1.11 % 2.03 % 10 +lstringa<40> e = "Test text"; auto c{e};_mean 5.24 ns 5.22 ns 10 +lstringa<40> e = "Test text"; auto c{e};_median 5.24 ns 5.23 ns 10 +lstringa<40> e = "Test text"; auto c{e};_stddev 0.068 ns 0.109 ns 10 +lstringa<40> e = "Test text"; auto c{e};_cv 1.30 % 2.09 % 10 +----- Create copy of Str with 30 symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "123456789012345678901234567890"; auto c{e};_mean 78.2 ns 78.0 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_median 77.6 ns 77.6 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_stddev 1.99 ns 2.73 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_cv 2.55 % 3.51 % 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_mean 0.741 ns 0.739 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_median 0.743 ns 0.741 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_stddev 0.008 ns 0.012 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_cv 1.14 % 1.65 % 10 +ssa e = "123456789012345678901234567890"; auto c{e};_mean 0.372 ns 0.370 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_median 0.374 ns 0.375 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_stddev 0.006 ns 0.013 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_cv 1.71 % 3.47 % 10 +stringa e = "123456789012345678901234567890"; auto c{e};_mean 1.89 ns 1.88 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_median 1.87 ns 1.88 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_stddev 0.045 ns 0.034 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_cv 2.36 % 1.78 % 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_mean 79.0 ns 78.0 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_median 78.7 ns 78.1 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_stddev 2.03 ns 1.80 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_cv 2.57 % 2.30 % 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_mean 4.95 ns 4.94 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_median 4.89 ns 4.84 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_stddev 0.243 ns 0.268 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_cv 4.91 % 5.42 % 10 +----- Find 9 symbols text in end of 99 symbols text ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string::find;_mean 39.5 ns 38.8 ns 10 +std::string::find;_median 38.9 ns 38.5 ns 10 +std::string::find;_stddev 1.56 ns 0.900 ns 10 +std::string::find;_cv 3.95 % 2.32 % 10 +std::string_view::find;_mean 39.1 ns 38.6 ns 10 +std::string_view::find;_median 39.0 ns 38.8 ns 10 +std::string_view::find;_stddev 0.455 ns 0.827 ns 10 +std::string_view::find;_cv 1.17 % 2.14 % 10 +ssa::find;_mean 18.2 ns 17.9 ns 10 +ssa::find;_median 18.2 ns 18.0 ns 10 +ssa::find;_stddev 0.242 ns 0.385 ns 10 +ssa::find;_cv 1.33 % 2.15 % 10 +stringa::find;_mean 18.8 ns 18.5 ns 10 +stringa::find;_median 18.4 ns 18.4 ns 10 +stringa::find;_stddev 0.795 ns 0.461 ns 10 +stringa::find;_cv 4.22 % 2.50 % 10 +lstringa<20>::find;_mean 18.2 ns 18.1 ns 10 +lstringa<20>::find;_median 18.0 ns 18.0 ns 10 +lstringa<20>::find;_stddev 0.505 ns 0.436 ns 10 +lstringa<20>::find;_cv 2.77 % 2.41 % 10 +lstringa<40>::find;_mean 17.8 ns 17.8 ns 10 +lstringa<40>::find;_median 17.8 ns 17.6 ns 10 +lstringa<40>::find;_stddev 0.232 ns 0.324 ns 10 +lstringa<40>::find;_cv 1.31 % 1.82 % 10 +------- Copy not literal Str with N symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string copy{str_with_len_N};/15_mean 1.85 ns 1.85 ns 10 +std::string copy{str_with_len_N};/15_median 1.85 ns 1.84 ns 10 +std::string copy{str_with_len_N};/15_stddev 0.041 ns 0.035 ns 10 +std::string copy{str_with_len_N};/15_cv 2.22 % 1.91 % 10 +std::string copy{str_with_len_N};/16_mean 80.4 ns 80.1 ns 10 +std::string copy{str_with_len_N};/16_median 80.4 ns 80.6 ns 10 +std::string copy{str_with_len_N};/16_stddev 1.57 ns 1.72 ns 10 +std::string copy{str_with_len_N};/16_cv 1.95 % 2.15 % 10 +std::string copy{str_with_len_N};/23_mean 81.2 ns 80.9 ns 10 +std::string copy{str_with_len_N};/23_median 80.8 ns 80.2 ns 10 +std::string copy{str_with_len_N};/23_stddev 2.51 ns 2.99 ns 10 +std::string copy{str_with_len_N};/23_cv 3.09 % 3.69 % 10 +std::string copy{str_with_len_N};/24_mean 80.9 ns 80.4 ns 10 +std::string copy{str_with_len_N};/24_median 80.6 ns 80.2 ns 10 +std::string copy{str_with_len_N};/24_stddev 1.27 ns 1.29 ns 10 +std::string copy{str_with_len_N};/24_cv 1.57 % 1.60 % 10 +std::string copy{str_with_len_N};/32_mean 85.9 ns 86.0 ns 10 +std::string copy{str_with_len_N};/32_median 86.3 ns 86.3 ns 10 +std::string copy{str_with_len_N};/32_stddev 1.08 ns 1.44 ns 10 +std::string copy{str_with_len_N};/32_cv 1.25 % 1.67 % 10 +std::string copy{str_with_len_N};/64_mean 87.1 ns 85.8 ns 10 +std::string copy{str_with_len_N};/64_median 86.4 ns 85.4 ns 10 +std::string copy{str_with_len_N};/64_stddev 3.35 ns 1.60 ns 10 +std::string copy{str_with_len_N};/64_cv 3.85 % 1.87 % 10 +std::string copy{str_with_len_N};/128_mean 90.3 ns 89.8 ns 10 +std::string copy{str_with_len_N};/128_median 89.0 ns 87.9 ns 10 +std::string copy{str_with_len_N};/128_stddev 6.26 ns 5.96 ns 10 +std::string copy{str_with_len_N};/128_cv 6.93 % 6.63 % 10 +std::string copy{str_with_len_N};/256_mean 87.8 ns 87.5 ns 10 +std::string copy{str_with_len_N};/256_median 86.8 ns 87.2 ns 10 +std::string copy{str_with_len_N};/256_stddev 2.33 ns 2.14 ns 10 +std::string copy{str_with_len_N};/256_cv 2.66 % 2.45 % 10 +std::string copy{str_with_len_N};/512_mean 90.4 ns 89.4 ns 10 +std::string copy{str_with_len_N};/512_median 90.1 ns 90.0 ns 10 +std::string copy{str_with_len_N};/512_stddev 2.20 ns 1.72 ns 10 +std::string copy{str_with_len_N};/512_cv 2.43 % 1.93 % 10 +std::string copy{str_with_len_N};/1024_mean 95.5 ns 94.6 ns 10 +std::string copy{str_with_len_N};/1024_median 94.5 ns 94.2 ns 10 +std::string copy{str_with_len_N};/1024_stddev 3.70 ns 2.93 ns 10 +std::string copy{str_with_len_N};/1024_cv 3.87 % 3.09 % 10 +std::string copy{str_with_len_N};/2048_mean 130 ns 129 ns 10 +std::string copy{str_with_len_N};/2048_median 130 ns 130 ns 10 +std::string copy{str_with_len_N};/2048_stddev 3.36 ns 2.70 ns 10 +std::string copy{str_with_len_N};/2048_cv 2.58 % 2.08 % 10 +std::string copy{str_with_len_N};/4096_mean 186 ns 185 ns 10 +std::string copy{str_with_len_N};/4096_median 184 ns 184 ns 10 +std::string copy{str_with_len_N};/4096_stddev 4.96 ns 2.83 ns 10 +std::string copy{str_with_len_N};/4096_cv 2.67 % 1.53 % 10 +stringa copy{str_with_len_N};/15_mean 1.31 ns 1.30 ns 10 +stringa copy{str_with_len_N};/15_median 1.31 ns 1.30 ns 10 +stringa copy{str_with_len_N};/15_stddev 0.035 ns 0.037 ns 10 +stringa copy{str_with_len_N};/15_cv 2.65 % 2.86 % 10 +stringa copy{str_with_len_N};/16_mean 1.31 ns 1.29 ns 10 +stringa copy{str_with_len_N};/16_median 1.30 ns 1.28 ns 10 +stringa copy{str_with_len_N};/16_stddev 0.028 ns 0.030 ns 10 +stringa copy{str_with_len_N};/16_cv 2.15 % 2.32 % 10 +stringa copy{str_with_len_N};/23_mean 1.30 ns 1.30 ns 10 +stringa copy{str_with_len_N};/23_median 1.29 ns 1.29 ns 10 +stringa copy{str_with_len_N};/23_stddev 0.038 ns 0.039 ns 10 +stringa copy{str_with_len_N};/23_cv 2.90 % 3.03 % 10 +stringa copy{str_with_len_N};/24_mean 16.1 ns 16.0 ns 10 +stringa copy{str_with_len_N};/24_median 16.0 ns 16.0 ns 10 +stringa copy{str_with_len_N};/24_stddev 0.320 ns 0.329 ns 10 +stringa copy{str_with_len_N};/24_cv 1.99 % 2.05 % 10 +stringa copy{str_with_len_N};/32_mean 16.3 ns 16.0 ns 10 +stringa copy{str_with_len_N};/32_median 16.1 ns 16.0 ns 10 +stringa copy{str_with_len_N};/32_stddev 0.543 ns 0.329 ns 10 +stringa copy{str_with_len_N};/32_cv 3.34 % 2.05 % 10 +stringa copy{str_with_len_N};/64_mean 16.0 ns 15.9 ns 10 +stringa copy{str_with_len_N};/64_median 16.0 ns 16.0 ns 10 +stringa copy{str_with_len_N};/64_stddev 0.094 ns 0.247 ns 10 +stringa copy{str_with_len_N};/64_cv 0.59 % 1.55 % 10 +stringa copy{str_with_len_N};/128_mean 16.1 ns 15.9 ns 10 +stringa copy{str_with_len_N};/128_median 16.1 ns 16.0 ns 10 +stringa copy{str_with_len_N};/128_stddev 0.106 ns 0.235 ns 10 +stringa copy{str_with_len_N};/128_cv 0.66 % 1.48 % 10 +stringa copy{str_with_len_N};/256_mean 16.0 ns 15.9 ns 10 +stringa copy{str_with_len_N};/256_median 16.0 ns 16.1 ns 10 +stringa copy{str_with_len_N};/256_stddev 0.111 ns 0.271 ns 10 +stringa copy{str_with_len_N};/256_cv 0.70 % 1.70 % 10 +stringa copy{str_with_len_N};/512_mean 16.0 ns 15.9 ns 10 +stringa copy{str_with_len_N};/512_median 16.0 ns 16.0 ns 10 +stringa copy{str_with_len_N};/512_stddev 0.128 ns 0.331 ns 10 +stringa copy{str_with_len_N};/512_cv 0.80 % 2.08 % 10 +stringa copy{str_with_len_N};/1024_mean 16.0 ns 15.9 ns 10 +stringa copy{str_with_len_N};/1024_median 16.0 ns 16.0 ns 10 +stringa copy{str_with_len_N};/1024_stddev 0.137 ns 0.180 ns 10 +stringa copy{str_with_len_N};/1024_cv 0.85 % 1.13 % 10 +stringa copy{str_with_len_N};/2048_mean 16.0 ns 15.9 ns 10 +stringa copy{str_with_len_N};/2048_median 16.0 ns 16.0 ns 10 +stringa copy{str_with_len_N};/2048_stddev 0.061 ns 0.235 ns 10 +stringa copy{str_with_len_N};/2048_cv 0.38 % 1.48 % 10 +stringa copy{str_with_len_N};/4096_mean 16.0 ns 15.8 ns 10 +stringa copy{str_with_len_N};/4096_median 15.9 ns 15.7 ns 10 +stringa copy{str_with_len_N};/4096_stddev 0.305 ns 0.275 ns 10 +stringa copy{str_with_len_N};/4096_cv 1.90 % 1.75 % 10 +lstringa<16> copy{str_with_len_N};/15_mean 4.85 ns 4.84 ns 10 +lstringa<16> copy{str_with_len_N};/15_median 4.85 ns 4.87 ns 10 +lstringa<16> copy{str_with_len_N};/15_stddev 0.072 ns 0.068 ns 10 +lstringa<16> copy{str_with_len_N};/15_cv 1.49 % 1.41 % 10 +lstringa<16> copy{str_with_len_N};/16_mean 4.83 ns 4.83 ns 10 +lstringa<16> copy{str_with_len_N};/16_median 4.83 ns 4.87 ns 10 +lstringa<16> copy{str_with_len_N};/16_stddev 0.077 ns 0.073 ns 10 +lstringa<16> copy{str_with_len_N};/16_cv 1.59 % 1.51 % 10 +lstringa<16> copy{str_with_len_N};/23_mean 4.89 ns 4.85 ns 10 +lstringa<16> copy{str_with_len_N};/23_median 4.88 ns 4.87 ns 10 +lstringa<16> copy{str_with_len_N};/23_stddev 0.055 ns 0.080 ns 10 +lstringa<16> copy{str_with_len_N};/23_cv 1.12 % 1.64 % 10 +lstringa<16> copy{str_with_len_N};/24_mean 83.5 ns 82.5 ns 10 +lstringa<16> copy{str_with_len_N};/24_median 83.0 ns 82.0 ns 10 +lstringa<16> copy{str_with_len_N};/24_stddev 2.42 ns 2.18 ns 10 +lstringa<16> copy{str_with_len_N};/24_cv 2.90 % 2.65 % 10 +lstringa<16> copy{str_with_len_N};/32_mean 85.8 ns 85.4 ns 10 +lstringa<16> copy{str_with_len_N};/32_median 84.3 ns 83.7 ns 10 +lstringa<16> copy{str_with_len_N};/32_stddev 4.76 ns 5.20 ns 10 +lstringa<16> copy{str_with_len_N};/32_cv 5.54 % 6.08 % 10 +lstringa<16> copy{str_with_len_N};/64_mean 81.4 ns 80.9 ns 10 +lstringa<16> copy{str_with_len_N};/64_median 81.8 ns 81.1 ns 10 +lstringa<16> copy{str_with_len_N};/64_stddev 1.99 ns 1.68 ns 10 +lstringa<16> copy{str_with_len_N};/64_cv 2.44 % 2.08 % 10 +lstringa<16> copy{str_with_len_N};/128_mean 84.3 ns 82.8 ns 10 +lstringa<16> copy{str_with_len_N};/128_median 83.9 ns 82.8 ns 10 +lstringa<16> copy{str_with_len_N};/128_stddev 3.17 ns 2.99 ns 10 +lstringa<16> copy{str_with_len_N};/128_cv 3.76 % 3.61 % 10 +lstringa<16> copy{str_with_len_N};/256_mean 85.1 ns 85.1 ns 10 +lstringa<16> copy{str_with_len_N};/256_median 84.5 ns 85.4 ns 10 +lstringa<16> copy{str_with_len_N};/256_stddev 2.13 ns 1.98 ns 10 +lstringa<16> copy{str_with_len_N};/256_cv 2.51 % 2.33 % 10 +lstringa<16> copy{str_with_len_N};/512_mean 89.0 ns 88.9 ns 10 +lstringa<16> copy{str_with_len_N};/512_median 87.4 ns 87.2 ns 10 +lstringa<16> copy{str_with_len_N};/512_stddev 5.89 ns 5.75 ns 10 +lstringa<16> copy{str_with_len_N};/512_cv 6.62 % 6.47 % 10 +lstringa<16> copy{str_with_len_N};/1024_mean 99.5 ns 99.0 ns 10 +lstringa<16> copy{str_with_len_N};/1024_median 97.4 ns 96.3 ns 10 +lstringa<16> copy{str_with_len_N};/1024_stddev 4.93 ns 4.53 ns 10 +lstringa<16> copy{str_with_len_N};/1024_cv 4.96 % 4.57 % 10 +lstringa<16> copy{str_with_len_N};/2048_mean 132 ns 130 ns 10 +lstringa<16> copy{str_with_len_N};/2048_median 130 ns 129 ns 10 +lstringa<16> copy{str_with_len_N};/2048_stddev 3.80 ns 3.05 ns 10 +lstringa<16> copy{str_with_len_N};/2048_cv 2.88 % 2.34 % 10 +lstringa<16> copy{str_with_len_N};/4096_mean 195 ns 194 ns 10 +lstringa<16> copy{str_with_len_N};/4096_median 195 ns 193 ns 10 +lstringa<16> copy{str_with_len_N};/4096_stddev 2.91 ns 3.97 ns 10 +lstringa<16> copy{str_with_len_N};/4096_cv 1.49 % 2.05 % 10 +lstringa<512> copy{str_with_len_N};/15_mean 5.57 ns 5.55 ns 10 +lstringa<512> copy{str_with_len_N};/15_median 5.56 ns 5.62 ns 10 +lstringa<512> copy{str_with_len_N};/15_stddev 0.097 ns 0.110 ns 10 +lstringa<512> copy{str_with_len_N};/15_cv 1.73 % 1.99 % 10 +lstringa<512> copy{str_with_len_N};/16_mean 5.69 ns 5.66 ns 10 +lstringa<512> copy{str_with_len_N};/16_median 5.63 ns 5.58 ns 10 +lstringa<512> copy{str_with_len_N};/16_stddev 0.225 ns 0.188 ns 10 +lstringa<512> copy{str_with_len_N};/16_cv 3.95 % 3.32 % 10 +lstringa<512> copy{str_with_len_N};/23_mean 5.60 ns 5.58 ns 10 +lstringa<512> copy{str_with_len_N};/23_median 5.63 ns 5.58 ns 10 +lstringa<512> copy{str_with_len_N};/23_stddev 0.105 ns 0.066 ns 10 +lstringa<512> copy{str_with_len_N};/23_cv 1.87 % 1.18 % 10 +lstringa<512> copy{str_with_len_N};/24_mean 5.59 ns 5.58 ns 10 +lstringa<512> copy{str_with_len_N};/24_median 5.60 ns 5.58 ns 10 +lstringa<512> copy{str_with_len_N};/24_stddev 0.075 ns 0.093 ns 10 +lstringa<512> copy{str_with_len_N};/24_cv 1.35 % 1.67 % 10 +lstringa<512> copy{str_with_len_N};/32_mean 8.48 ns 8.43 ns 10 +lstringa<512> copy{str_with_len_N};/32_median 8.48 ns 8.37 ns 10 +lstringa<512> copy{str_with_len_N};/32_stddev 0.137 ns 0.141 ns 10 +lstringa<512> copy{str_with_len_N};/32_cv 1.61 % 1.67 % 10 +lstringa<512> copy{str_with_len_N};/64_mean 8.74 ns 8.58 ns 10 +lstringa<512> copy{str_with_len_N};/64_median 8.62 ns 8.58 ns 10 +lstringa<512> copy{str_with_len_N};/64_stddev 0.367 ns 0.140 ns 10 +lstringa<512> copy{str_with_len_N};/64_cv 4.20 % 1.63 % 10 +lstringa<512> copy{str_with_len_N};/128_mean 8.99 ns 8.94 ns 10 +lstringa<512> copy{str_with_len_N};/128_median 8.96 ns 9.00 ns 10 +lstringa<512> copy{str_with_len_N};/128_stddev 0.220 ns 0.199 ns 10 +lstringa<512> copy{str_with_len_N};/128_cv 2.45 % 2.22 % 10 +lstringa<512> copy{str_with_len_N};/256_mean 10.1 ns 10.0 ns 10 +lstringa<512> copy{str_with_len_N};/256_median 10.0 ns 10.0 ns 10 +lstringa<512> copy{str_with_len_N};/256_stddev 0.247 ns 0.197 ns 10 +lstringa<512> copy{str_with_len_N};/256_cv 2.45 % 1.96 % 10 +lstringa<512> copy{str_with_len_N};/512_mean 11.8 ns 11.6 ns 10 +lstringa<512> copy{str_with_len_N};/512_median 11.7 ns 11.5 ns 10 +lstringa<512> copy{str_with_len_N};/512_stddev 0.325 ns 0.206 ns 10 +lstringa<512> copy{str_with_len_N};/512_cv 2.75 % 1.78 % 10 +lstringa<512> copy{str_with_len_N};/1024_mean 99.4 ns 99.1 ns 10 +lstringa<512> copy{str_with_len_N};/1024_median 97.7 ns 97.7 ns 10 +lstringa<512> copy{str_with_len_N};/1024_stddev 4.44 ns 5.66 ns 10 +lstringa<512> copy{str_with_len_N};/1024_cv 4.47 % 5.71 % 10 +lstringa<512> copy{str_with_len_N};/2048_mean 133 ns 133 ns 10 +lstringa<512> copy{str_with_len_N};/2048_median 132 ns 133 ns 10 +lstringa<512> copy{str_with_len_N};/2048_stddev 6.58 ns 6.87 ns 10 +lstringa<512> copy{str_with_len_N};/2048_cv 4.95 % 5.18 % 10 +lstringa<512> copy{str_with_len_N};/4096_mean 196 ns 195 ns 10 +lstringa<512> copy{str_with_len_N};/4096_median 196 ns 193 ns 10 +lstringa<512> copy{str_with_len_N};/4096_stddev 5.23 ns 2.96 ns 10 +lstringa<512> copy{str_with_len_N};/4096_cv 2.67 % 1.52 % 10 +----- Convert to int '1234567' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_mean 32.5 ns 31.7 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_median 31.9 ns 31.5 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_stddev 1.54 ns 0.927 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_cv 4.73 % 2.93 % 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_mean 13.8 ns 13.7 ns 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_median 13.8 ns 13.8 ns 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_stddev 0.262 ns 0.288 ns 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_cv 1.90 % 2.10 % 10 +stringa s = "123456789"; int res = s.to_int_mean 13.3 ns 13.2 ns 10 +stringa s = "123456789"; int res = s.to_int_median 13.3 ns 13.3 ns 10 +stringa s = "123456789"; int res = s.to_int_stddev 0.207 ns 0.270 ns 10 +stringa s = "123456789"; int res = s.to_int_cv 1.55 % 2.04 % 10 +ssa s = "123456789"; int res = s.to_int_mean 13.0 ns 13.0 ns 10 +ssa s = "123456789"; int res = s.to_int_median 13.1 ns 13.0 ns 10 +ssa s = "123456789"; int res = s.to_int_stddev 0.137 ns 0.237 ns 10 +ssa s = "123456789"; int res = s.to_int_cv 1.05 % 1.83 % 10 +lstringa<20> s = "123456789"; int res = s.to_int_mean 13.2 ns 13.2 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_median 13.3 ns 13.2 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_stddev 0.184 ns 0.232 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_cv 1.40 % 1.76 % 10 +----- Convert to unsigned 'abcDef' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_mean 34.4 ns 34.4 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_median 34.3 ns 34.1 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_stddev 0.621 ns 0.883 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_cv 1.80 % 2.57 % 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_mean 8.29 ns 8.28 ns 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_median 8.31 ns 8.28 ns 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_stddev 0.097 ns 0.148 ns 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_cv 1.17 % 1.79 % 10 +stringa s = "abcDef"; int res = s.to_int_mean 11.4 ns 11.4 ns 10 +stringa s = "abcDef"; int res = s.to_int_median 11.3 ns 11.4 ns 10 +stringa s = "abcDef"; int res = s.to_int_stddev 0.296 ns 0.327 ns 10 +stringa s = "abcDef"; int res = s.to_int_cv 2.59 % 2.86 % 10 +ssa s = "abcDef"; int res = s.to_int_mean 10.8 ns 10.7 ns 10 +ssa s = "abcDef"; int res = s.to_int_median 10.7 ns 10.7 ns 10 +ssa s = "abcDef"; int res = s.to_int_stddev 0.205 ns 0.230 ns 10 +ssa s = "abcDef"; int res = s.to_int_cv 1.91 % 2.14 % 10 +lstringa<20> s = "abcDef"; int res = s.to_int_mean 11.2 ns 11.1 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_median 11.2 ns 11.0 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_stddev 0.125 ns 0.262 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_cv 1.12 % 2.37 % 10 +----- Convert to int ' 1234567' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_mean 44.2 ns 43.9 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_median 43.9 ns 43.9 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_stddev 0.886 ns 1.22 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_cv 2.01 % 2.77 % 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_mean 18.8 ns 18.6 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_median 18.6 ns 18.6 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_stddev 0.412 ns 0.293 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_cv 2.20 % 1.57 % 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_mean 15.9 ns 15.8 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_median 15.9 ns 16.0 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_stddev 0.196 ns 0.294 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_cv 1.23 % 1.86 % 10 +-- Append const literal of 16 bytes 64 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << "abbaabbaabbaabba";_mean 7392 ns 7366 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_median 7379 ns 7324 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_stddev 138 ns 195 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_cv 1.87 % 2.65 % 10 +std::string str; ... str += "abbaabbaabbaabba";_mean 1068 ns 1060 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_median 1067 ns 1050 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_stddev 18.9 ns 26.2 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_cv 1.77 % 2.48 % 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_mean 757 ns 751 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_median 748 ns 753 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_stddev 19.1 ns 14.4 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_cv 2.52 % 1.92 % 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_mean 403 ns 399 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_median 391 ns 384 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_stddev 33.6 ns 33.1 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_cv 8.34 % 8.29 % 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_mean 229 ns 229 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_median 226 ns 225 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_stddev 6.65 ns 7.56 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_cv 2.91 % 3.31 % 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_mean 139 ns 139 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_median 139 ns 140 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_stddev 0.950 ns 1.88 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_cv 0.68 % 1.36 % 10 +-- Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_mean 6632 ns 6574 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_median 6640 ns 6539 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_stddev 127 ns 144 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_cv 1.92 % 2.18 % 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_mean 3901 ns 3892 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_median 3899 ns 3934 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_stddev 83.7 ns 81.3 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_cv 2.15 % 2.09 % 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_mean 763 ns 760 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_median 760 ns 753 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_stddev 17.7 ns 14.1 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_cv 2.32 % 1.86 % 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_mean 481 ns 473 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_median 474 ns 474 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_stddev 27.4 ns 12.2 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_cv 5.70 % 2.58 % 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_mean 306 ns 305 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_median 306 ns 305 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_stddev 10.0 ns 10.4 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_cv 3.28 % 3.40 % 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_mean 214 ns 213 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_median 213 ns 212 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_stddev 3.83 ns 4.72 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_cv 1.79 % 2.22 % 10 +-- Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_mean 361900 ns 360695 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_median 362008 ns 360695 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_stddev 8052 ns 8089 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_cv 2.23 % 2.24 % 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 199378 ns 199655 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 199446 ns 200911 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 3464 ns 4434 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 1.74 % 2.22 % 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 19852 ns 19796 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 19976 ns 19880 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 336 ns 443 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 1.69 % 2.24 % 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 18215 ns 18164 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 18175 ns 18206 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 300 ns 293 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 1.65 % 1.61 % 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 17973 ns 17955 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 17963 ns 17997 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 396 ns 461 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 2.20 % 2.57 % 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 17891 ns 17746 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 17888 ns 17788 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 237 ns 404 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 1.33 % 2.28 % 10 +-- Append 2 string of 16 bytes 32 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var1 << str_var2;_mean 6383 ns 6344 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_median 6406 ns 6406 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_stddev 115 ns 132 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_cv 1.80 % 2.08 % 10 +std::string str; ... str += str_var1 + str_var2;_mean 3986 ns 3993 ns 10 +std::string str; ... str += str_var1 + str_var2;_median 3990 ns 3984 ns 10 +std::string str; ... str += str_var1 + str_var2;_stddev 64.6 ns 62.6 ns 10 +std::string str; ... str += str_var1 + str_var2;_cv 1.62 % 1.57 % 10 +lstringa<16> str; ... str += str_var1 + str_var2;_mean 859 ns 856 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_median 846 ns 858 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_stddev 42.3 ns 40.0 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_cv 4.92 % 4.67 % 10 +lstringa<128> str; ... str += str_var1 + str_var2;_mean 569 ns 568 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_median 562 ns 558 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_stddev 25.2 ns 24.7 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_cv 4.42 % 4.34 % 10 +lstringa<512> str; ... str += str_var1 + str_var2;_mean 403 ns 400 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_median 401 ns 399 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_stddev 5.68 ns 6.69 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_cv 1.41 % 1.67 % 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_mean 314 ns 310 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_median 311 ns 307 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_stddev 15.1 ns 8.19 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_cv 4.80 % 2.64 % 10 +-- Append text, number, text --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; str << "test = " << k << " times";_mean 11663 ns 11597 ns 10 +std::stringstream str; str << "test = " << k << " times";_median 11672 ns 11597 ns 10 +std::stringstream str; str << "test = " << k << " times";_stddev 126 ns 129 ns 10 +std::stringstream str; str << "test = " << k << " times";_cv 1.08 % 1.11 % 10 +std::string str = "test = " + std::to_string(k) + " times";_mean 1114 ns 1110 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_median 1113 ns 1116 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_stddev 23.9 ns 22.0 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_cv 2.14 % 1.98 % 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_mean 2906 ns 2876 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_median 2888 ns 2849 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_stddev 81.9 ns 71.2 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_cv 2.82 % 2.48 % 10 +std::string str = std::format("test = {} times", k);_mean 1950 ns 1941 ns 10 +std::string str = std::format("test = {} times", k);_median 1942 ns 1904 ns 10 +std::string str = std::format("test = {} times", k);_stddev 57.0 ns 66.9 ns 10 +std::string str = std::format("test = {} times", k);_cv 2.92 % 3.45 % 10 +lstringa<8> str; str.format("test = {} times", k);_mean 2112 ns 2086 ns 10 +lstringa<8> str; str.format("test = {} times", k);_median 2107 ns 2086 ns 10 +lstringa<8> str; str.format("test = {} times", k);_stddev 28.2 ns 37.0 ns 10 +lstringa<8> str; str.format("test = {} times", k);_cv 1.33 % 1.77 % 10 +lstringa<32> str; str.format("test = {} times", k);_mean 1029 ns 1027 ns 10 +lstringa<32> str; str.format("test = {} times", k);_median 1031 ns 1036 ns 10 +lstringa<32> str; str.format("test = {} times", k);_stddev 22.3 ns 20.8 ns 10 +lstringa<32> str; str.format("test = {} times", k);_cv 2.17 % 2.03 % 10 +lstringa<8> str = "test = " + k + " times";_mean 823 ns 821 ns 10 +lstringa<8> str = "test = " + k + " times";_median 824 ns 820 ns 10 +lstringa<8> str = "test = " + k + " times";_stddev 20.8 ns 20.9 ns 10 +lstringa<8> str = "test = " + k + " times";_cv 2.53 % 2.54 % 10 +lstringa<32> str = "test = " + k + " times";_mean 160 ns 156 ns 10 +lstringa<32> str = "test = " + k + " times";_median 158 ns 155 ns 10 +lstringa<32> str = "test = " + k + " times";_stddev 6.73 ns 6.16 ns 10 +lstringa<32> str = "test = " + k + " times";_cv 4.21 % 3.95 % 10 +stringa str = "test = " + k + " times";_mean 156 ns 155 ns 10 +stringa str = "test = " + k + " times";_median 155 ns 153 ns 10 +stringa str = "test = " + k + " times";_stddev 4.05 ns 3.69 ns 10 +stringa str = "test = " + k + " times";_cv 2.60 % 2.39 % 10 +-- Split text and convert to int --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string::find + substr + std::strtol_mean 576 ns 573 ns 10 +std::string::find + substr + std::strtol_median 574 ns 572 ns 10 +std::string::find + substr + std::strtol_stddev 9.17 ns 12.2 ns 10 +std::string::find + substr + std::strtol_cv 1.59 % 2.13 % 10 +ssa::splitter + ssa::as_int_mean 173 ns 171 ns 10 +ssa::splitter + ssa::as_int_median 172 ns 171 ns 10 +ssa::splitter + ssa::as_int_stddev 3.44 ns 6.07 ns 10 +ssa::splitter + ssa::as_int_cv 1.99 % 3.55 % 10 +ssa::splitf + functor_mean 188 ns 187 ns 10 +ssa::splitf + functor_median 187 ns 186 ns 10 +ssa::splitf + functor_stddev 4.21 ns 5.57 ns 10 +ssa::splitf + functor_cv 2.23 % 2.98 % 10 +-- Replace symbols in text ~400 symbols --/repeats:1 0.000 ns 0.000 ns 1000000000 +Naive (and wrong) replace symbols with std::string find + replace_mean 1153 ns 1152 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_median 1163 ns 1160 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_stddev 21.3 ns 22.4 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_cv 1.85 % 1.95 % 10 +replace symbols with std::string find_first_of + replace_mean 2073 ns 2070 ns 10 +replace symbols with std::string find_first_of + replace_median 2069 ns 2051 ns 10 +replace symbols with std::string find_first_of + replace_stddev 48.9 ns 41.2 ns 10 +replace symbols with std::string find_first_of + replace_cv 2.36 % 1.99 % 10 +replace symbols with std::string_view find_first_of + copy_mean 2441 ns 2433 ns 10 +replace symbols with std::string_view find_first_of + copy_median 2447 ns 2455 ns 10 +replace symbols with std::string_view find_first_of + copy_stddev 40.0 ns 47.1 ns 10 +replace symbols with std::string_view find_first_of + copy_cv 1.64 % 1.93 % 10 +replace runtime symbols with string expressions and without remembering all search results_mean 1386 ns 1372 ns 10 +replace runtime symbols with string expressions and without remembering all search results_median 1386 ns 1365 ns 10 +replace runtime symbols with string expressions and without remembering all search results_stddev 27.9 ns 42.0 ns 10 +replace runtime symbols with string expressions and without remembering all search results_cv 2.01 % 3.06 % 10 +replace runtime symbols with simstr and memorization of all search results_mean 1373 ns 1362 ns 10 +replace runtime symbols with simstr and memorization of all search results_median 1367 ns 1381 ns 10 +replace runtime symbols with simstr and memorization of all search results_stddev 67.1 ns 57.7 ns 10 +replace runtime symbols with simstr and memorization of all search results_cv 4.89 % 4.23 % 10 +replace const symbols with string expressions and without remembering all search results_mean 1213 ns 1211 ns 10 +replace const symbols with string expressions and without remembering all search results_median 1210 ns 1200 ns 10 +replace const symbols with string expressions and without remembering all search results_stddev 28.4 ns 19.5 ns 10 +replace const symbols with string expressions and without remembering all search results_cv 2.34 % 1.61 % 10 +replace const symbols with string expressions and memorization of all search results_mean 1228 ns 1203 ns 10 +replace const symbols with string expressions and memorization of all search results_median 1218 ns 1200 ns 10 +replace const symbols with string expressions and memorization of all search results_stddev 38.9 ns 24.4 ns 10 +replace const symbols with string expressions and memorization of all search results_cv 3.17 % 2.03 % 10 +-- Replace symbols in text ~40 symbols --/repeats:1 0.000 ns 0.000 ns 1000000000 +Short Naive (and wrong) replace symbols with std::string find + replace_mean 321 ns 319 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_median 322 ns 317 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_stddev 4.92 ns 6.62 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_cv 1.53 % 2.08 % 10 +Short replace symbols with std::string find_first_of + replace_mean 378 ns 377 ns 10 +Short replace symbols with std::string find_first_of + replace_median 377 ns 377 ns 10 +Short replace symbols with std::string find_first_of + replace_stddev 8.10 ns 11.8 ns 10 +Short replace symbols with std::string find_first_of + replace_cv 2.14 % 3.14 % 10 +Short replace symbols with std::string_view find_first_of + copy_mean 342 ns 340 ns 10 +Short replace symbols with std::string_view find_first_of + copy_median 343 ns 341 ns 10 +Short replace symbols with std::string_view find_first_of + copy_stddev 4.68 ns 6.32 ns 10 +Short replace symbols with std::string_view find_first_of + copy_cv 1.37 % 1.86 % 10 +Short replace runtime symbols with string expressions and without remembering all search results_mean 251 ns 247 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_median 251 ns 246 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_stddev 2.57 ns 5.91 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_cv 1.02 % 2.39 % 10 +Short replace runtime symbols with simstr and memorization of all search results_mean 347 ns 344 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_median 344 ns 344 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_stddev 7.13 ns 6.91 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_cv 2.06 % 2.01 % 10 +Short replace const symbols with string expressions and without remembering all search results_mean 218 ns 217 ns 10 +Short replace const symbols with string expressions and without remembering all search results_median 220 ns 217 ns 10 +Short replace const symbols with string expressions and without remembering all search results_stddev 4.90 ns 5.27 ns 10 +Short replace const symbols with string expressions and without remembering all search results_cv 2.25 % 2.43 % 10 +Short replace const symbols with string expressions and memorization of all search results_mean 301 ns 300 ns 10 +Short replace const symbols with string expressions and memorization of all search results_median 300 ns 300 ns 10 +Short replace const symbols with string expressions and memorization of all search results_stddev 6.51 ns 5.70 ns 10 +Short replace const symbols with string expressions and memorization of all search results_cv 2.16 % 1.90 % 10 +----- Replace All Str To Longer Size ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +replace bb to ---- in std::string|64_mean 238 ns 237 ns 10 +replace bb to ---- in std::string|64_median 239 ns 238 ns 10 +replace bb to ---- in std::string|64_stddev 4.84 ns 5.54 ns 10 +replace bb to ---- in std::string|64_cv 2.03 % 2.34 % 10 +replace bb to ---- in std::string|256_mean 779 ns 771 ns 10 +replace bb to ---- in std::string|256_median 775 ns 767 ns 10 +replace bb to ---- in std::string|256_stddev 25.1 ns 16.0 ns 10 +replace bb to ---- in std::string|256_cv 3.23 % 2.08 % 10 +replace bb to ---- in std::string|512_mean 1450 ns 1444 ns 10 +replace bb to ---- in std::string|512_median 1452 ns 1430 ns 10 +replace bb to ---- in std::string|512_stddev 29.1 ns 29.4 ns 10 +replace bb to ---- in std::string|512_cv 2.01 % 2.04 % 10 +replace bb to ---- in std::string|1024_mean 3246 ns 3230 ns 10 +replace bb to ---- in std::string|1024_median 3193 ns 3209 ns 10 +replace bb to ---- in std::string|1024_stddev 122 ns 114 ns 10 +replace bb to ---- in std::string|1024_cv 3.76 % 3.53 % 10 +replace bb to ---- in std::string|2048_mean 8153 ns 8057 ns 10 +replace bb to ---- in std::string|2048_median 7974 ns 8022 ns 10 +replace bb to ---- in std::string|2048_stddev 374 ns 257 ns 10 +replace bb to ---- in std::string|2048_cv 4.59 % 3.19 % 10 +replace bb to ---- in lstringa<8>|64_mean 343 ns 342 ns 10 +replace bb to ---- in lstringa<8>|64_median 342 ns 341 ns 10 +replace bb to ---- in lstringa<8>|64_stddev 6.86 ns 5.61 ns 10 +replace bb to ---- in lstringa<8>|64_cv 2.00 % 1.64 % 10 +replace bb to ---- in lstringa<8>|256_mean 645 ns 646 ns 10 +replace bb to ---- in lstringa<8>|256_median 644 ns 642 ns 10 +replace bb to ---- in lstringa<8>|256_stddev 13.7 ns 14.8 ns 10 +replace bb to ---- in lstringa<8>|256_cv 2.12 % 2.29 % 10 +replace bb to ---- in lstringa<8>|512_mean 1080 ns 1072 ns 10 +replace bb to ---- in lstringa<8>|512_median 1078 ns 1074 ns 10 +replace bb to ---- in lstringa<8>|512_stddev 23.2 ns 24.3 ns 10 +replace bb to ---- in lstringa<8>|512_cv 2.14 % 2.27 % 10 +replace bb to ---- in lstringa<8>|1024_mean 1916 ns 1904 ns 10 +replace bb to ---- in lstringa<8>|1024_median 1910 ns 1904 ns 10 +replace bb to ---- in lstringa<8>|1024_stddev 31.6 ns 42.7 ns 10 +replace bb to ---- in lstringa<8>|1024_cv 1.65 % 2.24 % 10 +replace bb to ---- in lstringa<8>|2048_mean 3650 ns 3618 ns 10 +replace bb to ---- in lstringa<8>|2048_median 3650 ns 3610 ns 10 +replace bb to ---- in lstringa<8>|2048_stddev 32.9 ns 59.2 ns 10 +replace bb to ---- in lstringa<8>|2048_cv 0.90 % 1.64 % 10 +replace bb to ---- by init stringa|64_mean 216 ns 216 ns 10 +replace bb to ---- by init stringa|64_median 215 ns 214 ns 10 +replace bb to ---- by init stringa|64_stddev 8.87 ns 8.47 ns 10 +replace bb to ---- by init stringa|64_cv 4.10 % 3.93 % 10 +replace bb to ---- by init stringa|256_mean 548 ns 547 ns 10 +replace bb to ---- by init stringa|256_median 546 ns 547 ns 10 +replace bb to ---- by init stringa|256_stddev 9.01 ns 12.8 ns 10 +replace bb to ---- by init stringa|256_cv 1.64 % 2.33 % 10 +replace bb to ---- by init stringa|512_mean 941 ns 942 ns 10 +replace bb to ---- by init stringa|512_median 942 ns 942 ns 10 +replace bb to ---- by init stringa|512_stddev 22.7 ns 24.2 ns 10 +replace bb to ---- by init stringa|512_cv 2.41 % 2.57 % 10 +replace bb to ---- by init stringa|1024_mean 1775 ns 1765 ns 10 +replace bb to ---- by init stringa|1024_median 1766 ns 1765 ns 10 +replace bb to ---- by init stringa|1024_stddev 33.7 ns 31.3 ns 10 +replace bb to ---- by init stringa|1024_cv 1.90 % 1.77 % 10 +replace bb to ---- by init stringa|2048_mean 3478 ns 3450 ns 10 +replace bb to ---- by init stringa|2048_median 3489 ns 3442 ns 10 +replace bb to ---- by init stringa|2048_stddev 48.5 ns 54.0 ns 10 +replace bb to ---- by init stringa|2048_cv 1.39 % 1.57 % 10 +----- Replace All Str To Same Size ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +replace bb to -- in std::string|64_mean 196 ns 195 ns 10 +replace bb to -- in std::string|64_median 196 ns 197 ns 10 +replace bb to -- in std::string|64_stddev 2.59 ns 3.53 ns 10 +replace bb to -- in std::string|64_cv 1.32 % 1.81 % 10 +replace bb to -- in std::string|256_mean 503 ns 500 ns 10 +replace bb to -- in std::string|256_median 501 ns 500 ns 10 +replace bb to -- in std::string|256_stddev 8.11 ns 10.4 ns 10 +replace bb to -- in std::string|256_cv 1.61 % 2.08 % 10 +replace bb to -- in std::string|512_mean 864 ns 861 ns 10 +replace bb to -- in std::string|512_median 868 ns 854 ns 10 +replace bb to -- in std::string|512_stddev 17.6 ns 18.7 ns 10 +replace bb to -- in std::string|512_cv 2.04 % 2.18 % 10 +replace bb to -- in std::string|1024_mean 1700 ns 1684 ns 10 +replace bb to -- in std::string|1024_median 1702 ns 1688 ns 10 +replace bb to -- in std::string|1024_stddev 27.7 ns 28.3 ns 10 +replace bb to -- in std::string|1024_cv 1.63 % 1.68 % 10 +replace bb to -- in std::string|2048_mean 3239 ns 3230 ns 10 +replace bb to -- in std::string|2048_median 3196 ns 3209 ns 10 +replace bb to -- in std::string|2048_stddev 103 ns 123 ns 10 +replace bb to -- in std::string|2048_cv 3.18 % 3.82 % 10 +replace bb to -- in lstringa<8>|64_mean 192 ns 191 ns 10 +replace bb to -- in lstringa<8>|64_median 189 ns 188 ns 10 +replace bb to -- in lstringa<8>|64_stddev 8.04 ns 7.43 ns 10 +replace bb to -- in lstringa<8>|64_cv 4.19 % 3.90 % 10 +replace bb to -- in lstringa<8>|256_mean 452 ns 450 ns 10 +replace bb to -- in lstringa<8>|256_median 452 ns 449 ns 10 +replace bb to -- in lstringa<8>|256_stddev 9.20 ns 12.6 ns 10 +replace bb to -- in lstringa<8>|256_cv 2.04 % 2.79 % 10 +replace bb to -- in lstringa<8>|512_mean 797 ns 790 ns 10 +replace bb to -- in lstringa<8>|512_median 796 ns 785 ns 10 +replace bb to -- in lstringa<8>|512_stddev 11.3 ns 14.4 ns 10 +replace bb to -- in lstringa<8>|512_cv 1.42 % 1.82 % 10 +replace bb to -- in lstringa<8>|1024_mean 1444 ns 1437 ns 10 +replace bb to -- in lstringa<8>|1024_median 1435 ns 1430 ns 10 +replace bb to -- in lstringa<8>|1024_stddev 28.8 ns 39.6 ns 10 +replace bb to -- in lstringa<8>|1024_cv 2.00 % 2.76 % 10 +replace bb to -- in lstringa<8>|2048_mean 2839 ns 2844 ns 10 +replace bb to -- in lstringa<8>|2048_median 2831 ns 2825 ns 10 +replace bb to -- in lstringa<8>|2048_stddev 55.3 ns 78.6 ns 10 +replace bb to -- in lstringa<8>|2048_cv 1.95 % 2.76 % 10 +replace bb to -- by init stringa|64_mean 167 ns 166 ns 10 +replace bb to -- by init stringa|64_median 167 ns 165 ns 10 +replace bb to -- by init stringa|64_stddev 5.30 ns 3.96 ns 10 +replace bb to -- by init stringa|64_cv 3.17 % 2.39 % 10 +replace bb to -- by init stringa|256_mean 352 ns 351 ns 10 +replace bb to -- by init stringa|256_median 353 ns 353 ns 10 +replace bb to -- by init stringa|256_stddev 4.26 ns 5.07 ns 10 +replace bb to -- by init stringa|256_cv 1.21 % 1.44 % 10 +replace bb to -- by init stringa|512_mean 598 ns 596 ns 10 +replace bb to -- by init stringa|512_median 597 ns 600 ns 10 +replace bb to -- by init stringa|512_stddev 11.5 ns 14.8 ns 10 +replace bb to -- by init stringa|512_cv 1.92 % 2.48 % 10 +replace bb to -- by init stringa|1024_mean 1082 ns 1078 ns 10 +replace bb to -- by init stringa|1024_median 1084 ns 1088 ns 10 +replace bb to -- by init stringa|1024_stddev 24.1 ns 28.3 ns 10 +replace bb to -- by init stringa|1024_cv 2.23 % 2.63 % 10 +replace bb to -- by init stringa|2048_mean 1963 ns 1963 ns 10 +replace bb to -- by init stringa|2048_median 1964 ns 1967 ns 10 +replace bb to -- by init stringa|2048_stddev 29.4 ns 36.6 ns 10 +replace bb to -- by init stringa|2048_cv 1.50 % 1.87 % 10 +----- Hash Map insert and find ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +hashStrMapA emplace & find stringa;_mean 4144900 ns 4132154 ns 10 +hashStrMapA emplace & find stringa;_median 4145547 ns 4094503 ns 10 +hashStrMapA emplace & find stringa;_stddev 160485 ns 168671 ns 10 +hashStrMapA emplace & find stringa;_cv 3.87 % 4.08 % 10 +std::unordered_map emplace & find std::string;_mean 5984962 ns 5929129 ns 10 +std::unordered_map emplace & find std::string;_median 5980382 ns 5929129 ns 10 +std::unordered_map emplace & find std::string;_stddev 115002 ns 118560 ns 10 +std::unordered_map emplace & find std::string;_cv 1.92 % 2.00 % 10 +hashStrMapA emplace & find ssa;_mean 3983708 ns 3942587 ns 10 +hashStrMapA emplace & find ssa;_median 3962420 ns 3906250 ns 10 +hashStrMapA emplace & find ssa;_stddev 76626 ns 97653 ns 10 +hashStrMapA emplace & find ssa;_cv 1.92 % 2.48 % 10 +std::unordered_map emplace & find std::string_view;_mean 7030276 ns 7003348 ns 10 +std::unordered_map emplace & find std::string_view;_median 6994535 ns 6975446 ns 10 +std::unordered_map emplace & find std::string_view;_stddev 131572 ns 158383 ns 10 +std::unordered_map emplace & find std::string_view;_cv 1.87 % 2.26 % 10 +----- Build Full Func Name ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +Build func full name std::string;_mean 1588 ns 1580 ns 10 +Build func full name std::string;_median 1583 ns 1569 ns 10 +Build func full name std::string;_stddev 33.8 ns 33.1 ns 10 +Build func full name std::string;_cv 2.13 % 2.09 % 10 +Build func full name std::string 1;_mean 1648 ns 1638 ns 10 +Build func full name std::string 1;_median 1626 ns 1631 ns 10 +Build func full name std::string 1;_stddev 60.0 ns 57.3 ns 10 +Build func full name std::string 1;_cv 3.64 % 3.50 % 10 +Build func full name std::stream;_mean 10979 ns 10718 ns 10 +Build func full name std::stream;_median 10840 ns 10742 ns 10 +Build func full name std::stream;_stddev 530 ns 269 ns 10 +Build func full name std::stream;_cv 4.82 % 2.51 % 10 +Build func full name stringa;_mean 847 ns 844 ns 10 +Build func full name stringa;_median 844 ns 837 ns 10 +Build func full name stringa;_stddev 22.6 ns 20.5 ns 10 +Build func full name stringa;_cv 2.66 % 2.43 % 10 +Build func full name stringa 1;_mean 1003 ns 998 ns 10 +Build func full name stringa 1;_median 999 ns 1004 ns 10 +Build func full name stringa 1;_stddev 12.7 ns 14.1 ns 10 +Build func full name stringa 1;_cv 1.27 % 1.41 % 10 diff --git a/bench/results/003-Xeon E5-2682 v4, Windows 10, MSVC-19.txt b/bench/results/003-Xeon E5-2682 v4, Windows 10, MSVC-19.txt new file mode 100644 index 0000000..baadaf7 --- /dev/null +++ b/bench/results/003-Xeon E5-2682 v4, Windows 10, MSVC-19.txt @@ -0,0 +1,777 @@ +2025-08-06T12:39:51+03:00 +Running benchStr.exe +Run on (32 X 2497.21 MHz CPU s) +CPU Caches: + L1 Data 32 KiB (x16) + L1 Instruction 32 KiB (x16) + L2 Unified 256 KiB (x16) + L3 Unified 40960 KiB (x1) +-------------------------------------------------------------------------------------------------------------------------------------------------------- +Benchmark Time CPU Iterations +-------------------------------------------------------------------------------------------------------------------------------------------------------- +----- Create Empty Str ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e;_mean 2.59 ns 2.58 ns 10 +std::string e;_median 2.60 ns 2.61 ns 10 +std::string e;_stddev 0.037 ns 0.081 ns 10 +std::string e;_cv 1.42 % 3.13 % 10 +std::string_view e;_mean 1.86 ns 1.84 ns 10 +std::string_view e;_median 1.85 ns 1.84 ns 10 +std::string_view e;_stddev 0.025 ns 0.040 ns 10 +std::string_view e;_cv 1.33 % 2.20 % 10 +ssa e;_mean 1.84 ns 1.84 ns 10 +ssa e;_median 1.84 ns 1.81 ns 10 +ssa e;_stddev 0.033 ns 0.044 ns 10 +ssa e;_cv 1.79 % 2.40 % 10 +stringa e;_mean 2.22 ns 2.22 ns 10 +stringa e;_median 2.23 ns 2.22 ns 10 +stringa e;_stddev 0.034 ns 0.034 ns 10 +stringa e;_cv 1.53 % 1.54 % 10 +lstringa<20> e;_mean 2.62 ns 2.60 ns 10 +lstringa<20> e;_median 2.59 ns 2.61 ns 10 +lstringa<20> e;_stddev 0.136 ns 0.078 ns 10 +lstringa<20> e;_cv 5.18 % 3.01 % 10 +lstringa<40> e;_mean 2.60 ns 2.58 ns 10 +lstringa<40> e;_median 2.61 ns 2.57 ns 10 +lstringa<40> e;_stddev 0.049 ns 0.051 ns 10 +lstringa<40> e;_cv 1.86 % 1.99 % 10 +----- Create Str from short literal (9 symbols) --------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "Test text";_mean 2.61 ns 2.59 ns 10 +std::string e = "Test text";_median 2.61 ns 2.61 ns 10 +std::string e = "Test text";_stddev 0.056 ns 0.064 ns 10 +std::string e = "Test text";_cv 2.16 % 2.47 % 10 +std::string_view e = "Test text";_mean 1.83 ns 1.83 ns 10 +std::string_view e = "Test text";_median 1.83 ns 1.82 ns 10 +std::string_view e = "Test text";_stddev 0.027 ns 0.034 ns 10 +std::string_view e = "Test text";_cv 1.45 % 1.88 % 10 +ssa e = "Test text";_mean 1.84 ns 1.84 ns 10 +ssa e = "Test text";_median 1.83 ns 1.84 ns 10 +ssa e = "Test text";_stddev 0.029 ns 0.037 ns 10 +ssa e = "Test text";_cv 1.57 % 1.99 % 10 +stringa e = "Test text";_mean 2.60 ns 2.59 ns 10 +stringa e = "Test text";_median 2.60 ns 2.58 ns 10 +stringa e = "Test text";_stddev 0.040 ns 0.041 ns 10 +stringa e = "Test text";_cv 1.52 % 1.60 % 10 +lstringa<20> e = "Test text";_mean 2.25 ns 2.25 ns 10 +lstringa<20> e = "Test text";_median 2.25 ns 2.25 ns 10 +lstringa<20> e = "Test text";_stddev 0.031 ns 0.033 ns 10 +lstringa<20> e = "Test text";_cv 1.38 % 1.45 % 10 +lstringa<40> e = "Test text";_mean 2.63 ns 2.62 ns 10 +lstringa<40> e = "Test text";_median 2.62 ns 2.62 ns 10 +lstringa<40> e = "Test text";_stddev 0.063 ns 0.053 ns 10 +lstringa<40> e = "Test text";_cv 2.41 % 2.01 % 10 +----- Create Str from long literal (30 symbols) ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "123456789012345678901234567890";_mean 74.8 ns 74.8 ns 10 +std::string e = "123456789012345678901234567890";_median 75.4 ns 75.0 ns 10 +std::string e = "123456789012345678901234567890";_stddev 1.69 ns 1.73 ns 10 +std::string e = "123456789012345678901234567890";_cv 2.26 % 2.32 % 10 +std::string_view e = "123456789012345678901234567890";_mean 1.84 ns 1.83 ns 10 +std::string_view e = "123456789012345678901234567890";_median 1.84 ns 1.84 ns 10 +std::string_view e = "123456789012345678901234567890";_stddev 0.018 ns 0.028 ns 10 +std::string_view e = "123456789012345678901234567890";_cv 1.00 % 1.54 % 10 +ssa e = "123456789012345678901234567890";_mean 1.85 ns 1.85 ns 10 +ssa e = "123456789012345678901234567890";_median 1.85 ns 1.84 ns 10 +ssa e = "123456789012345678901234567890";_stddev 0.022 ns 0.026 ns 10 +ssa e = "123456789012345678901234567890";_cv 1.17 % 1.43 % 10 +stringa e = "123456789012345678901234567890";_mean 2.92 ns 2.88 ns 10 +stringa e = "123456789012345678901234567890";_median 2.89 ns 2.89 ns 10 +stringa e = "123456789012345678901234567890";_stddev 0.100 ns 0.026 ns 10 +stringa e = "123456789012345678901234567890";_cv 3.43 % 0.92 % 10 +lstringa<20> e = "123456789012345678901234567890";_mean 76.7 ns 76.0 ns 10 +lstringa<20> e = "123456789012345678901234567890";_median 76.7 ns 76.7 ns 10 +lstringa<20> e = "123456789012345678901234567890";_stddev 1.13 ns 1.47 ns 10 +lstringa<20> e = "123456789012345678901234567890";_cv 1.48 % 1.93 % 10 +lstringa<40> e = "123456789012345678901234567890";_mean 3.01 ns 2.99 ns 10 +lstringa<40> e = "123456789012345678901234567890";_median 3.01 ns 2.95 ns 10 +lstringa<40> e = "123456789012345678901234567890";_stddev 0.059 ns 0.079 ns 10 +lstringa<40> e = "123456789012345678901234567890";_cv 1.96 % 2.62 % 10 +----- Create copy of Str with 9 symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "Test text"; auto c{e};_mean 5.16 ns 5.13 ns 10 +std::string e = "Test text"; auto c{e};_median 5.17 ns 5.16 ns 10 +std::string e = "Test text"; auto c{e};_stddev 0.099 ns 0.128 ns 10 +std::string e = "Test text"; auto c{e};_cv 1.91 % 2.50 % 10 +std::string_view e = "Test text"; auto c{e};_mean 3.74 ns 3.73 ns 10 +std::string_view e = "Test text"; auto c{e};_median 3.73 ns 3.75 ns 10 +std::string_view e = "Test text"; auto c{e};_stddev 0.024 ns 0.055 ns 10 +std::string_view e = "Test text"; auto c{e};_cv 0.64 % 1.48 % 10 +ssa e = "Test text"; auto c{e};_mean 3.75 ns 3.74 ns 10 +ssa e = "Test text"; auto c{e};_median 3.75 ns 3.77 ns 10 +ssa e = "Test text"; auto c{e};_stddev 0.023 ns 0.040 ns 10 +ssa e = "Test text"; auto c{e};_cv 0.62 % 1.08 % 10 +stringa e = "Test text"; auto c{e};_mean 4.07 ns 4.06 ns 10 +stringa e = "Test text"; auto c{e};_median 4.08 ns 4.05 ns 10 +stringa e = "Test text"; auto c{e};_stddev 0.031 ns 0.069 ns 10 +stringa e = "Test text"; auto c{e};_cv 0.76 % 1.71 % 10 +lstringa<20> e = "Test text"; auto c{e};_mean 8.64 ns 8.62 ns 10 +lstringa<20> e = "Test text"; auto c{e};_median 8.54 ns 8.58 ns 10 +lstringa<20> e = "Test text"; auto c{e};_stddev 0.240 ns 0.276 ns 10 +lstringa<20> e = "Test text"; auto c{e};_cv 2.78 % 3.20 % 10 +lstringa<40> e = "Test text"; auto c{e};_mean 8.46 ns 8.44 ns 10 +lstringa<40> e = "Test text"; auto c{e};_median 8.46 ns 8.37 ns 10 +lstringa<40> e = "Test text"; auto c{e};_stddev 0.110 ns 0.147 ns 10 +lstringa<40> e = "Test text"; auto c{e};_cv 1.29 % 1.74 % 10 +----- Create copy of Str with 30 symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "123456789012345678901234567890"; auto c{e};_mean 76.3 ns 75.5 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_median 75.7 ns 75.0 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_stddev 3.22 ns 2.61 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_cv 4.22 % 3.45 % 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_mean 1.84 ns 1.84 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_median 1.84 ns 1.84 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_stddev 0.018 ns 0.034 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_cv 1.00 % 1.86 % 10 +ssa e = "123456789012345678901234567890"; auto c{e};_mean 1.87 ns 1.84 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_median 1.85 ns 1.84 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_stddev 0.110 ns 0.034 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_cv 5.87 % 1.86 % 10 +stringa e = "123456789012345678901234567890"; auto c{e};_mean 2.97 ns 2.96 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_median 2.97 ns 2.95 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_stddev 0.045 ns 0.078 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_cv 1.53 % 2.63 % 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_mean 82.0 ns 82.0 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_median 81.4 ns 82.0 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_stddev 2.62 ns 2.47 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_cv 3.20 % 3.01 % 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_mean 7.05 ns 7.05 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_median 7.04 ns 7.11 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_stddev 0.058 ns 0.099 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_cv 0.83 % 1.40 % 10 +----- Find 9 symbols text in end of 99 symbols text ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string::find;_mean 42.5 ns 42.2 ns 10 +std::string::find;_median 41.6 ns 41.0 ns 10 +std::string::find;_stddev 3.23 ns 3.41 ns 10 +std::string::find;_cv 7.61 % 8.08 % 10 +std::string_view::find;_mean 41.5 ns 40.8 ns 10 +std::string_view::find;_median 41.0 ns 40.8 ns 10 +std::string_view::find;_stddev 1.46 ns 0.855 ns 10 +std::string_view::find;_cv 3.52 % 2.10 % 10 +ssa::find;_mean 21.1 ns 21.0 ns 10 +ssa::find;_median 21.2 ns 20.9 ns 10 +ssa::find;_stddev 0.338 ns 0.430 ns 10 +ssa::find;_cv 1.60 % 2.05 % 10 +stringa::find;_mean 32.2 ns 32.2 ns 10 +stringa::find;_median 32.2 ns 32.1 ns 10 +stringa::find;_stddev 1.30 ns 1.22 ns 10 +stringa::find;_cv 4.02 % 3.79 % 10 +lstringa<20>::find;_mean 21.3 ns 21.2 ns 10 +lstringa<20>::find;_median 21.2 ns 21.1 ns 10 +lstringa<20>::find;_stddev 0.530 ns 0.526 ns 10 +lstringa<20>::find;_cv 2.49 % 2.48 % 10 +lstringa<40>::find;_mean 21.6 ns 21.4 ns 10 +lstringa<40>::find;_median 21.5 ns 21.5 ns 10 +lstringa<40>::find;_stddev 0.399 ns 0.428 ns 10 +lstringa<40>::find;_cv 1.85 % 1.99 % 10 +------- Copy not literal Str with N symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string copy{str_with_len_N};/15_mean 5.18 ns 5.15 ns 10 +std::string copy{str_with_len_N};/15_median 5.18 ns 5.16 ns 10 +std::string copy{str_with_len_N};/15_stddev 0.073 ns 0.122 ns 10 +std::string copy{str_with_len_N};/15_cv 1.42 % 2.37 % 10 +std::string copy{str_with_len_N};/16_mean 84.9 ns 83.5 ns 10 +std::string copy{str_with_len_N};/16_median 83.6 ns 83.7 ns 10 +std::string copy{str_with_len_N};/16_stddev 3.62 ns 2.39 ns 10 +std::string copy{str_with_len_N};/16_cv 4.26 % 2.86 % 10 +std::string copy{str_with_len_N};/23_mean 85.1 ns 84.5 ns 10 +std::string copy{str_with_len_N};/23_median 84.5 ns 83.7 ns 10 +std::string copy{str_with_len_N};/23_stddev 3.10 ns 2.88 ns 10 +std::string copy{str_with_len_N};/23_cv 3.64 % 3.41 % 10 +std::string copy{str_with_len_N};/24_mean 83.1 ns 82.7 ns 10 +std::string copy{str_with_len_N};/24_median 83.3 ns 83.7 ns 10 +std::string copy{str_with_len_N};/24_stddev 1.97 ns 2.75 ns 10 +std::string copy{str_with_len_N};/24_cv 2.37 % 3.33 % 10 +std::string copy{str_with_len_N};/32_mean 89.1 ns 87.9 ns 10 +std::string copy{str_with_len_N};/32_median 89.5 ns 87.9 ns 10 +std::string copy{str_with_len_N};/32_stddev 1.88 ns 2.21 ns 10 +std::string copy{str_with_len_N};/32_cv 2.11 % 2.51 % 10 +std::string copy{str_with_len_N};/64_mean 89.7 ns 89.1 ns 10 +std::string copy{str_with_len_N};/64_median 89.3 ns 90.0 ns 10 +std::string copy{str_with_len_N};/64_stddev 3.48 ns 2.82 ns 10 +std::string copy{str_with_len_N};/64_cv 3.88 % 3.17 % 10 +std::string copy{str_with_len_N};/128_mean 89.0 ns 88.3 ns 10 +std::string copy{str_with_len_N};/128_median 89.4 ns 87.9 ns 10 +std::string copy{str_with_len_N};/128_stddev 1.67 ns 1.65 ns 10 +std::string copy{str_with_len_N};/128_cv 1.88 % 1.87 % 10 +std::string copy{str_with_len_N};/256_mean 91.5 ns 89.6 ns 10 +std::string copy{str_with_len_N};/256_median 90.9 ns 90.0 ns 10 +std::string copy{str_with_len_N};/256_stddev 3.43 ns 2.38 ns 10 +std::string copy{str_with_len_N};/256_cv 3.75 % 2.65 % 10 +std::string copy{str_with_len_N};/512_mean 93.8 ns 93.5 ns 10 +std::string copy{str_with_len_N};/512_median 94.0 ns 94.2 ns 10 +std::string copy{str_with_len_N};/512_stddev 1.39 ns 1.99 ns 10 +std::string copy{str_with_len_N};/512_cv 1.48 % 2.12 % 10 +std::string copy{str_with_len_N};/1024_mean 99.5 ns 99.4 ns 10 +std::string copy{str_with_len_N};/1024_median 99.3 ns 98.4 ns 10 +std::string copy{str_with_len_N};/1024_stddev 2.81 ns 3.31 ns 10 +std::string copy{str_with_len_N};/1024_cv 2.82 % 3.33 % 10 +std::string copy{str_with_len_N};/2048_mean 132 ns 131 ns 10 +std::string copy{str_with_len_N};/2048_median 133 ns 131 ns 10 +std::string copy{str_with_len_N};/2048_stddev 6.13 ns 5.17 ns 10 +std::string copy{str_with_len_N};/2048_cv 4.64 % 3.95 % 10 +std::string copy{str_with_len_N};/4096_mean 181 ns 180 ns 10 +std::string copy{str_with_len_N};/4096_median 182 ns 182 ns 10 +std::string copy{str_with_len_N};/4096_stddev 3.84 ns 4.83 ns 10 +std::string copy{str_with_len_N};/4096_cv 2.12 % 2.69 % 10 +stringa copy{str_with_len_N};/15_mean 4.15 ns 4.06 ns 10 +stringa copy{str_with_len_N};/15_median 4.12 ns 4.08 ns 10 +stringa copy{str_with_len_N};/15_stddev 0.168 ns 0.083 ns 10 +stringa copy{str_with_len_N};/15_cv 4.04 % 2.05 % 10 +stringa copy{str_with_len_N};/16_mean 4.11 ns 4.10 ns 10 +stringa copy{str_with_len_N};/16_median 4.11 ns 4.08 ns 10 +stringa copy{str_with_len_N};/16_stddev 0.036 ns 0.057 ns 10 +stringa copy{str_with_len_N};/16_cv 0.88 % 1.40 % 10 +stringa copy{str_with_len_N};/23_mean 4.13 ns 4.13 ns 10 +stringa copy{str_with_len_N};/23_median 4.12 ns 4.13 ns 10 +stringa copy{str_with_len_N};/23_stddev 0.051 ns 0.077 ns 10 +stringa copy{str_with_len_N};/23_cv 1.22 % 1.87 % 10 +stringa copy{str_with_len_N};/24_mean 18.7 ns 18.6 ns 10 +stringa copy{str_with_len_N};/24_median 18.6 ns 18.6 ns 10 +stringa copy{str_with_len_N};/24_stddev 0.128 ns 0.293 ns 10 +stringa copy{str_with_len_N};/24_cv 0.68 % 1.57 % 10 +stringa copy{str_with_len_N};/32_mean 18.6 ns 18.5 ns 10 +stringa copy{str_with_len_N};/32_median 18.6 ns 18.4 ns 10 +stringa copy{str_with_len_N};/32_stddev 0.118 ns 0.243 ns 10 +stringa copy{str_with_len_N};/32_cv 0.64 % 1.31 % 10 +stringa copy{str_with_len_N};/64_mean 18.6 ns 18.6 ns 10 +stringa copy{str_with_len_N};/64_median 18.6 ns 18.6 ns 10 +stringa copy{str_with_len_N};/64_stddev 0.168 ns 0.221 ns 10 +stringa copy{str_with_len_N};/64_cv 0.90 % 1.18 % 10 +stringa copy{str_with_len_N};/128_mean 18.6 ns 18.5 ns 10 +stringa copy{str_with_len_N};/128_median 18.6 ns 18.4 ns 10 +stringa copy{str_with_len_N};/128_stddev 0.180 ns 0.243 ns 10 +stringa copy{str_with_len_N};/128_cv 0.97 % 1.31 % 10 +stringa copy{str_with_len_N};/256_mean 18.6 ns 18.5 ns 10 +stringa copy{str_with_len_N};/256_median 18.6 ns 18.4 ns 10 +stringa copy{str_with_len_N};/256_stddev 0.089 ns 0.283 ns 10 +stringa copy{str_with_len_N};/256_cv 0.48 % 1.53 % 10 +stringa copy{str_with_len_N};/512_mean 18.7 ns 18.6 ns 10 +stringa copy{str_with_len_N};/512_median 18.6 ns 18.4 ns 10 +stringa copy{str_with_len_N};/512_stddev 0.388 ns 0.324 ns 10 +stringa copy{str_with_len_N};/512_cv 2.07 % 1.74 % 10 +stringa copy{str_with_len_N};/1024_mean 18.6 ns 18.6 ns 10 +stringa copy{str_with_len_N};/1024_median 18.6 ns 18.4 ns 10 +stringa copy{str_with_len_N};/1024_stddev 0.199 ns 0.268 ns 10 +stringa copy{str_with_len_N};/1024_cv 1.07 % 1.44 % 10 +stringa copy{str_with_len_N};/2048_mean 18.8 ns 18.5 ns 10 +stringa copy{str_with_len_N};/2048_median 18.6 ns 18.4 ns 10 +stringa copy{str_with_len_N};/2048_stddev 0.774 ns 0.265 ns 10 +stringa copy{str_with_len_N};/2048_cv 4.11 % 1.43 % 10 +stringa copy{str_with_len_N};/4096_mean 18.5 ns 18.4 ns 10 +stringa copy{str_with_len_N};/4096_median 18.5 ns 18.4 ns 10 +stringa copy{str_with_len_N};/4096_stddev 0.111 ns 0.309 ns 10 +stringa copy{str_with_len_N};/4096_cv 0.60 % 1.68 % 10 +lstringa<16> copy{str_with_len_N};/15_mean 8.67 ns 8.66 ns 10 +lstringa<16> copy{str_with_len_N};/15_median 8.62 ns 8.58 ns 10 +lstringa<16> copy{str_with_len_N};/15_stddev 0.415 ns 0.409 ns 10 +lstringa<16> copy{str_with_len_N};/15_cv 4.78 % 4.72 % 10 +lstringa<16> copy{str_with_len_N};/16_mean 8.61 ns 8.58 ns 10 +lstringa<16> copy{str_with_len_N};/16_median 8.57 ns 8.54 ns 10 +lstringa<16> copy{str_with_len_N};/16_stddev 0.177 ns 0.138 ns 10 +lstringa<16> copy{str_with_len_N};/16_cv 2.06 % 1.60 % 10 +lstringa<16> copy{str_with_len_N};/23_mean 8.58 ns 8.56 ns 10 +lstringa<16> copy{str_with_len_N};/23_median 8.57 ns 8.54 ns 10 +lstringa<16> copy{str_with_len_N};/23_stddev 0.127 ns 0.173 ns 10 +lstringa<16> copy{str_with_len_N};/23_cv 1.48 % 2.03 % 10 +lstringa<16> copy{str_with_len_N};/24_mean 80.5 ns 80.1 ns 10 +lstringa<16> copy{str_with_len_N};/24_median 81.1 ns 79.5 ns 10 +lstringa<16> copy{str_with_len_N};/24_stddev 2.02 ns 2.43 ns 10 +lstringa<16> copy{str_with_len_N};/24_cv 2.50 % 3.03 % 10 +lstringa<16> copy{str_with_len_N};/32_mean 83.1 ns 81.6 ns 10 +lstringa<16> copy{str_with_len_N};/32_median 82.9 ns 82.7 ns 10 +lstringa<16> copy{str_with_len_N};/32_stddev 3.13 ns 3.12 ns 10 +lstringa<16> copy{str_with_len_N};/32_cv 3.76 % 3.82 % 10 +lstringa<16> copy{str_with_len_N};/64_mean 83.1 ns 82.5 ns 10 +lstringa<16> copy{str_with_len_N};/64_median 83.1 ns 83.7 ns 10 +lstringa<16> copy{str_with_len_N};/64_stddev 2.31 ns 2.47 ns 10 +lstringa<16> copy{str_with_len_N};/64_cv 2.78 % 3.00 % 10 +lstringa<16> copy{str_with_len_N};/128_mean 86.5 ns 85.6 ns 10 +lstringa<16> copy{str_with_len_N};/128_median 86.4 ns 85.4 ns 10 +lstringa<16> copy{str_with_len_N};/128_stddev 1.40 ns 0.990 ns 10 +lstringa<16> copy{str_with_len_N};/128_cv 1.61 % 1.16 % 10 +lstringa<16> copy{str_with_len_N};/256_mean 89.8 ns 88.7 ns 10 +lstringa<16> copy{str_with_len_N};/256_median 89.3 ns 87.9 ns 10 +lstringa<16> copy{str_with_len_N};/256_stddev 3.02 ns 2.65 ns 10 +lstringa<16> copy{str_with_len_N};/256_cv 3.37 % 2.98 % 10 +lstringa<16> copy{str_with_len_N};/512_mean 90.8 ns 90.2 ns 10 +lstringa<16> copy{str_with_len_N};/512_median 90.4 ns 90.0 ns 10 +lstringa<16> copy{str_with_len_N};/512_stddev 2.53 ns 2.87 ns 10 +lstringa<16> copy{str_with_len_N};/512_cv 2.78 % 3.18 % 10 +lstringa<16> copy{str_with_len_N};/1024_mean 101 ns 99.6 ns 10 +lstringa<16> copy{str_with_len_N};/1024_median 101 ns 98.4 ns 10 +lstringa<16> copy{str_with_len_N};/1024_stddev 4.94 ns 3.97 ns 10 +lstringa<16> copy{str_with_len_N};/1024_cv 4.88 % 3.99 % 10 +lstringa<16> copy{str_with_len_N};/2048_mean 131 ns 130 ns 10 +lstringa<16> copy{str_with_len_N};/2048_median 129 ns 128 ns 10 +lstringa<16> copy{str_with_len_N};/2048_stddev 4.11 ns 4.60 ns 10 +lstringa<16> copy{str_with_len_N};/2048_cv 3.13 % 3.55 % 10 +lstringa<16> copy{str_with_len_N};/4096_mean 192 ns 189 ns 10 +lstringa<16> copy{str_with_len_N};/4096_median 192 ns 188 ns 10 +lstringa<16> copy{str_with_len_N};/4096_stddev 4.74 ns 2.65 ns 10 +lstringa<16> copy{str_with_len_N};/4096_cv 2.47 % 1.40 % 10 +lstringa<512> copy{str_with_len_N};/15_mean 8.47 ns 8.46 ns 10 +lstringa<512> copy{str_with_len_N};/15_median 8.45 ns 8.46 ns 10 +lstringa<512> copy{str_with_len_N};/15_stddev 0.064 ns 0.092 ns 10 +lstringa<512> copy{str_with_len_N};/15_cv 0.76 % 1.09 % 10 +lstringa<512> copy{str_with_len_N};/16_mean 8.59 ns 8.54 ns 10 +lstringa<512> copy{str_with_len_N};/16_median 8.59 ns 8.58 ns 10 +lstringa<512> copy{str_with_len_N};/16_stddev 0.112 ns 0.165 ns 10 +lstringa<512> copy{str_with_len_N};/16_cv 1.31 % 1.93 % 10 +lstringa<512> copy{str_with_len_N};/23_mean 8.48 ns 8.48 ns 10 +lstringa<512> copy{str_with_len_N};/23_median 8.47 ns 8.48 ns 10 +lstringa<512> copy{str_with_len_N};/23_stddev 0.099 ns 0.110 ns 10 +lstringa<512> copy{str_with_len_N};/23_cv 1.16 % 1.30 % 10 +lstringa<512> copy{str_with_len_N};/24_mean 8.60 ns 8.42 ns 10 +lstringa<512> copy{str_with_len_N};/24_median 8.49 ns 8.37 ns 10 +lstringa<512> copy{str_with_len_N};/24_stddev 0.400 ns 0.165 ns 10 +lstringa<512> copy{str_with_len_N};/24_cv 4.65 % 1.96 % 10 +lstringa<512> copy{str_with_len_N};/32_mean 11.7 ns 11.5 ns 10 +lstringa<512> copy{str_with_len_N};/32_median 11.5 ns 11.5 ns 10 +lstringa<512> copy{str_with_len_N};/32_stddev 0.459 ns 0.365 ns 10 +lstringa<512> copy{str_with_len_N};/32_cv 3.93 % 3.16 % 10 +lstringa<512> copy{str_with_len_N};/64_mean 11.6 ns 11.6 ns 10 +lstringa<512> copy{str_with_len_N};/64_median 11.6 ns 11.6 ns 10 +lstringa<512> copy{str_with_len_N};/64_stddev 0.274 ns 0.171 ns 10 +lstringa<512> copy{str_with_len_N};/64_cv 2.36 % 1.48 % 10 +lstringa<512> copy{str_with_len_N};/128_mean 11.9 ns 11.9 ns 10 +lstringa<512> copy{str_with_len_N};/128_median 11.9 ns 11.8 ns 10 +lstringa<512> copy{str_with_len_N};/128_stddev 0.201 ns 0.236 ns 10 +lstringa<512> copy{str_with_len_N};/128_cv 1.69 % 1.99 % 10 +lstringa<512> copy{str_with_len_N};/256_mean 13.0 ns 12.9 ns 10 +lstringa<512> copy{str_with_len_N};/256_median 12.9 ns 12.8 ns 10 +lstringa<512> copy{str_with_len_N};/256_stddev 0.235 ns 0.176 ns 10 +lstringa<512> copy{str_with_len_N};/256_cv 1.80 % 1.37 % 10 +lstringa<512> copy{str_with_len_N};/512_mean 14.6 ns 14.4 ns 10 +lstringa<512> copy{str_with_len_N};/512_median 14.5 ns 14.4 ns 10 +lstringa<512> copy{str_with_len_N};/512_stddev 0.500 ns 0.232 ns 10 +lstringa<512> copy{str_with_len_N};/512_cv 3.43 % 1.61 % 10 +lstringa<512> copy{str_with_len_N};/1024_mean 101 ns 100 ns 10 +lstringa<512> copy{str_with_len_N};/1024_median 99.2 ns 100 ns 10 +lstringa<512> copy{str_with_len_N};/1024_stddev 4.55 ns 3.64 ns 10 +lstringa<512> copy{str_with_len_N};/1024_cv 4.53 % 3.64 % 10 +lstringa<512> copy{str_with_len_N};/2048_mean 130 ns 129 ns 10 +lstringa<512> copy{str_with_len_N};/2048_median 129 ns 128 ns 10 +lstringa<512> copy{str_with_len_N};/2048_stddev 3.39 ns 3.90 ns 10 +lstringa<512> copy{str_with_len_N};/2048_cv 2.61 % 3.03 % 10 +lstringa<512> copy{str_with_len_N};/4096_mean 192 ns 192 ns 10 +lstringa<512> copy{str_with_len_N};/4096_median 192 ns 193 ns 10 +lstringa<512> copy{str_with_len_N};/4096_stddev 3.24 ns 3.85 ns 10 +lstringa<512> copy{str_with_len_N};/4096_cv 1.69 % 2.01 % 10 +----- Convert to int '1234567' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_mean 33.7 ns 33.5 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_median 33.7 ns 33.3 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_stddev 0.541 ns 0.756 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_cv 1.60 % 2.26 % 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_mean 17.9 ns 17.9 ns 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_median 17.9 ns 17.6 ns 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_stddev 0.358 ns 0.443 ns 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);_cv 2.00 % 2.48 % 10 +stringa s = "123456789"; int res = s.to_int_mean 15.4 ns 15.3 ns 10 +stringa s = "123456789"; int res = s.to_int_median 15.4 ns 15.4 ns 10 +stringa s = "123456789"; int res = s.to_int_stddev 0.153 ns 0.258 ns 10 +stringa s = "123456789"; int res = s.to_int_cv 1.00 % 1.69 % 10 +ssa s = "123456789"; int res = s.to_int_mean 15.1 ns 15.1 ns 10 +ssa s = "123456789"; int res = s.to_int_median 15.0 ns 15.1 ns 10 +ssa s = "123456789"; int res = s.to_int_stddev 0.250 ns 0.362 ns 10 +ssa s = "123456789"; int res = s.to_int_cv 1.66 % 2.41 % 10 +lstringa<20> s = "123456789"; int res = s.to_int_mean 14.9 ns 14.8 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_median 15.0 ns 14.9 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_stddev 0.290 ns 0.333 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_cv 1.94 % 2.24 % 10 +----- Convert to unsigned 'abcDef' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_mean 36.1 ns 35.7 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_median 36.1 ns 36.0 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_stddev 0.420 ns 0.971 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_cv 1.16 % 2.72 % 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_mean 10.1 ns 10.0 ns 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_median 10.1 ns 10.0 ns 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_stddev 0.165 ns 0.208 ns 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);_cv 1.64 % 2.08 % 10 +stringa s = "abcDef"; int res = s.to_int_mean 13.8 ns 13.6 ns 10 +stringa s = "abcDef"; int res = s.to_int_median 13.6 ns 13.7 ns 10 +stringa s = "abcDef"; int res = s.to_int_stddev 0.516 ns 0.244 ns 10 +stringa s = "abcDef"; int res = s.to_int_cv 3.74 % 1.79 % 10 +ssa s = "abcDef"; int res = s.to_int_mean 12.8 ns 12.8 ns 10 +ssa s = "abcDef"; int res = s.to_int_median 12.8 ns 12.8 ns 10 +ssa s = "abcDef"; int res = s.to_int_stddev 0.202 ns 0.158 ns 10 +ssa s = "abcDef"; int res = s.to_int_cv 1.58 % 1.24 % 10 +lstringa<20> s = "abcDef"; int res = s.to_int_mean 12.8 ns 12.6 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_median 12.8 ns 12.6 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_stddev 0.167 ns 0.265 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_cv 1.30 % 2.09 % 10 +----- Convert to int ' 1234567' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_mean 48.8 ns 48.1 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_median 48.9 ns 48.4 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_stddev 1.84 ns 1.44 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_cv 3.76 % 2.98 % 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_mean 22.4 ns 22.2 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_median 22.3 ns 22.2 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_stddev 0.215 ns 0.366 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_cv 0.96 % 1.65 % 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_mean 19.0 ns 19.0 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_median 19.0 ns 18.8 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_stddev 0.223 ns 0.293 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_cv 1.17 % 1.54 % 10 +-- Append const literal of 16 bytes 64 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << "abbaabbaabbaabba";_mean 5758 ns 5734 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_median 5729 ns 5720 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_stddev 141 ns 180 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_cv 2.44 % 3.13 % 10 +std::string str; ... str += "abbaabbaabbaabba";_mean 1327 ns 1318 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_median 1326 ns 1318 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_stddev 26.7 ns 25.6 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_cv 2.01 % 1.94 % 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_mean 972 ns 963 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_median 953 ns 963 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_stddev 53.6 ns 39.5 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_cv 5.52 % 4.10 % 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_mean 539 ns 536 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_median 538 ns 537 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_stddev 13.9 ns 19.9 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_cv 2.59 % 3.72 % 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_mean 371 ns 370 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_median 371 ns 372 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_stddev 4.64 ns 9.50 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_cv 1.25 % 2.57 % 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_mean 235 ns 231 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_median 232 ns 229 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_stddev 7.10 ns 7.30 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_cv 3.02 % 3.16 % 10 +-- Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_mean 5986 ns 5984 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_median 5935 ns 5938 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_stddev 197 ns 196 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_cv 3.29 % 3.27 % 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_mean 3929 ns 3917 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_median 3847 ns 3850 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_stddev 165 ns 136 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_cv 4.20 % 3.46 % 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_mean 849 ns 837 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_median 843 ns 837 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_stddev 25.5 ns 18.4 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_cv 3.00 % 2.20 % 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_mean 550 ns 550 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_median 550 ns 544 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_stddev 12.6 ns 15.0 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_cv 2.30 % 2.73 % 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_mean 388 ns 383 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_median 387 ns 385 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_stddev 11.3 ns 9.11 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_cv 2.91 % 2.38 % 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_mean 271 ns 271 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_median 268 ns 267 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_stddev 6.37 ns 6.28 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_cv 2.35 % 2.32 % 10 +-- Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_mean 285644 ns 283121 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_median 284822 ns 282493 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_stddev 5319 ns 7516 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_cv 1.86 % 2.65 % 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 194551 ns 194632 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 192304 ns 192540 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 4793 ns 5313 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 2.46 % 2.73 % 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 23615 ns 23490 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 23822 ns 23542 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 534 ns 626 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 2.26 % 2.67 % 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 22280 ns 22119 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 22301 ns 21973 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 236 ns 463 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 1.06 % 2.09 % 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 22335 ns 22119 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 22202 ns 21973 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 749 ns 566 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 3.35 % 2.56 % 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 21663 ns 21582 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 21492 ns 21484 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 516 ns 385 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 2.38 % 1.78 % 10 +-- Append 2 string of 16 bytes 32 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var1 << str_var2;_mean 5491 ns 5500 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_median 5477 ns 5469 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_stddev 117 ns 177 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_cv 2.14 % 3.23 % 10 +std::string str; ... str += str_var1 + str_var2;_mean 3997 ns 3990 ns 10 +std::string str; ... str += str_var1 + str_var2;_median 3983 ns 3990 ns 10 +std::string str; ... str += str_var1 + str_var2;_stddev 96.0 ns 113 ns 10 +std::string str; ... str += str_var1 + str_var2;_cv 2.40 % 2.83 % 10 +lstringa<16> str; ... str += str_var1 + str_var2;_mean 958 ns 950 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_median 951 ns 952 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_stddev 33.2 ns 29.2 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_cv 3.47 % 3.08 % 10 +lstringa<128> str; ... str += str_var1 + str_var2;_mean 664 ns 661 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_median 637 ns 637 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_stddev 70.1 ns 70.9 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_cv 10.56 % 10.73 % 10 +lstringa<512> str; ... str += str_var1 + str_var2;_mean 483 ns 476 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_median 479 ns 476 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_stddev 16.5 ns 5.51 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_cv 3.42 % 1.16 % 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_mean 381 ns 375 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_median 375 ns 372 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_stddev 13.7 ns 15.5 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_cv 3.59 % 4.14 % 10 +-- Append text, number, text --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; str << "test = " << k << " times";_mean 11615 ns 11579 ns 10 +std::stringstream str; str << "test = " << k << " times";_median 11545 ns 11440 ns 10 +std::stringstream str; str << "test = " << k << " times";_stddev 250 ns 271 ns 10 +std::stringstream str; str << "test = " << k << " times";_cv 2.15 % 2.34 % 10 +std::string str = "test = " + std::to_string(k) + " times";_mean 1260 ns 1256 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_median 1258 ns 1242 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_stddev 43.2 ns 50.9 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_cv 3.43 % 4.06 % 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_mean 2855 ns 2846 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_median 2847 ns 2846 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_stddev 56.7 ns 39.5 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_cv 1.98 % 1.39 % 10 +std::string str = std::format("test = {} times", k);_mean 2420 ns 2399 ns 10 +std::string str = std::format("test = {} times", k);_median 2407 ns 2403 ns 10 +std::string str = std::format("test = {} times", k);_stddev 56.2 ns 39.7 ns 10 +std::string str = std::format("test = {} times", k);_cv 2.32 % 1.66 % 10 +lstringa<8> str; str.format("test = {} times", k);_mean 2609 ns 2585 ns 10 +lstringa<8> str; str.format("test = {} times", k);_median 2633 ns 2609 ns 10 +lstringa<8> str; str.format("test = {} times", k);_stddev 64.8 ns 63.7 ns 10 +lstringa<8> str; str.format("test = {} times", k);_cv 2.48 % 2.47 % 10 +lstringa<32> str; str.format("test = {} times", k);_mean 1549 ns 1545 ns 10 +lstringa<32> str; str.format("test = {} times", k);_median 1544 ns 1535 ns 10 +lstringa<32> str; str.format("test = {} times", k);_stddev 22.3 ns 23.5 ns 10 +lstringa<32> str; str.format("test = {} times", k);_cv 1.44 % 1.52 % 10 +lstringa<8> str = "test = " + k + " times";_mean 949 ns 935 ns 10 +lstringa<8> str = "test = " + k + " times";_median 932 ns 921 ns 10 +lstringa<8> str = "test = " + k + " times";_stddev 47.9 ns 44.2 ns 10 +lstringa<8> str = "test = " + k + " times";_cv 5.05 % 4.72 % 10 +lstringa<32> str = "test = " + k + " times";_mean 191 ns 190 ns 10 +lstringa<32> str = "test = " + k + " times";_median 191 ns 190 ns 10 +lstringa<32> str = "test = " + k + " times";_stddev 3.14 ns 4.78 ns 10 +lstringa<32> str = "test = " + k + " times";_cv 1.64 % 2.51 % 10 +stringa str = "test = " + k + " times";_mean 241 ns 239 ns 10 +stringa str = "test = " + k + " times";_median 240 ns 241 ns 10 +stringa str = "test = " + k + " times";_stddev 2.40 ns 5.54 ns 10 +stringa str = "test = " + k + " times";_cv 1.00 % 2.32 % 10 +-- Split text and convert to int --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string::find + substr + std::strtol_mean 555 ns 547 ns 10 +std::string::find + substr + std::strtol_median 553 ns 547 ns 10 +std::string::find + substr + std::strtol_stddev 16.8 ns 12.8 ns 10 +std::string::find + substr + std::strtol_cv 3.02 % 2.33 % 10 +ssa::splitter + ssa::as_int_mean 289 ns 288 ns 10 +ssa::splitter + ssa::as_int_median 289 ns 286 ns 10 +ssa::splitter + ssa::as_int_stddev 7.31 ns 9.10 ns 10 +ssa::splitter + ssa::as_int_cv 2.53 % 3.16 % 10 +ssa::splitf + functor_mean 207 ns 207 ns 10 +ssa::splitf + functor_median 206 ns 209 ns 10 +ssa::splitf + functor_stddev 3.00 ns 2.70 ns 10 +ssa::splitf + functor_cv 1.45 % 1.30 % 10 +-- Replace symbols in text ~400 symbols --/repeats:1 0.000 ns 0.000 ns 1000000000 +Naive (and wrong) replace symbols with std::string find + replace_mean 1303 ns 1294 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_median 1294 ns 1290 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_stddev 44.5 ns 53.1 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_cv 3.42 % 4.11 % 10 +replace symbols with std::string find_first_of + replace_mean 2205 ns 2204 ns 10 +replace symbols with std::string find_first_of + replace_median 2177 ns 2176 ns 10 +replace symbols with std::string find_first_of + replace_stddev 62.9 ns 68.3 ns 10 +replace symbols with std::string find_first_of + replace_cv 2.85 % 3.10 % 10 +replace symbols with std::string_view find_first_of + copy_mean 2625 ns 2595 ns 10 +replace symbols with std::string_view find_first_of + copy_median 2598 ns 2567 ns 10 +replace symbols with std::string_view find_first_of + copy_stddev 88.9 ns 80.0 ns 10 +replace symbols with std::string_view find_first_of + copy_cv 3.39 % 3.08 % 10 +replace runtime symbols with string expressions and without remembering all search results_mean 1555 ns 1542 ns 10 +replace runtime symbols with string expressions and without remembering all search results_median 1558 ns 1535 ns 10 +replace runtime symbols with string expressions and without remembering all search results_stddev 33.3 ns 43.6 ns 10 +replace runtime symbols with string expressions and without remembering all search results_cv 2.14 % 2.82 % 10 +replace runtime symbols with simstr and memorization of all search results_mean 1382 ns 1381 ns 10 +replace runtime symbols with simstr and memorization of all search results_median 1376 ns 1381 ns 10 +replace runtime symbols with simstr and memorization of all search results_stddev 22.5 ns 29.6 ns 10 +replace runtime symbols with simstr and memorization of all search results_cv 1.63 % 2.14 % 10 +replace const symbols with string expressions and without remembering all search results_mean 1277 ns 1268 ns 10 +replace const symbols with string expressions and without remembering all search results_median 1275 ns 1271 ns 10 +replace const symbols with string expressions and without remembering all search results_stddev 18.6 ns 21.9 ns 10 +replace const symbols with string expressions and without remembering all search results_cv 1.46 % 1.73 % 10 +replace const symbols with string expressions and memorization of all search results_mean 1266 ns 1256 ns 10 +replace const symbols with string expressions and memorization of all search results_median 1253 ns 1256 ns 10 +replace const symbols with string expressions and memorization of all search results_stddev 43.0 ns 37.2 ns 10 +replace const symbols with string expressions and memorization of all search results_cv 3.40 % 2.96 % 10 +-- Replace symbols in text ~40 symbols --/repeats:1 0.000 ns 0.000 ns 1000000000 +Short Naive (and wrong) replace symbols with std::string find + replace_mean 329 ns 328 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_median 328 ns 328 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_stddev 10.2 ns 9.86 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_cv 3.12 % 3.01 % 10 +Short replace symbols with std::string find_first_of + replace_mean 429 ns 428 ns 10 +Short replace symbols with std::string find_first_of + replace_median 427 ns 424 ns 10 +Short replace symbols with std::string find_first_of + replace_stddev 7.85 ns 10.1 ns 10 +Short replace symbols with std::string find_first_of + replace_cv 1.83 % 2.37 % 10 +Short replace symbols with std::string_view find_first_of + copy_mean 363 ns 362 ns 10 +Short replace symbols with std::string_view find_first_of + copy_median 363 ns 364 ns 10 +Short replace symbols with std::string_view find_first_of + copy_stddev 7.84 ns 8.87 ns 10 +Short replace symbols with std::string_view find_first_of + copy_cv 2.16 % 2.45 % 10 +Short replace runtime symbols with string expressions and without remembering all search results_mean 279 ns 278 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_median 279 ns 276 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_stddev 5.50 ns 4.24 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_cv 1.97 % 1.52 % 10 +Short replace runtime symbols with simstr and memorization of all search results_mean 389 ns 384 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_median 387 ns 384 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_stddev 14.2 ns 13.0 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_cv 3.65 % 3.39 % 10 +Short replace const symbols with string expressions and without remembering all search results_mean 248 ns 244 ns 10 +Short replace const symbols with string expressions and without remembering all search results_median 246 ns 246 ns 10 +Short replace const symbols with string expressions and without remembering all search results_stddev 10.1 ns 6.86 ns 10 +Short replace const symbols with string expressions and without remembering all search results_cv 4.09 % 2.81 % 10 +Short replace const symbols with string expressions and memorization of all search results_mean 354 ns 352 ns 10 +Short replace const symbols with string expressions and memorization of all search results_median 349 ns 353 ns 10 +Short replace const symbols with string expressions and memorization of all search results_stddev 14.4 ns 12.8 ns 10 +Short replace const symbols with string expressions and memorization of all search results_cv 4.07 % 3.63 % 10 +----- Replace All Str To Longer Size ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +replace bb to ---- in std::string|64_mean 245 ns 243 ns 10 +replace bb to ---- in std::string|64_median 246 ns 246 ns 10 +replace bb to ---- in std::string|64_stddev 3.99 ns 5.42 ns 10 +replace bb to ---- in std::string|64_cv 1.63 % 2.23 % 10 +replace bb to ---- in std::string|256_mean 852 ns 849 ns 10 +replace bb to ---- in std::string|256_median 846 ns 846 ns 10 +replace bb to ---- in std::string|256_stddev 23.7 ns 24.7 ns 10 +replace bb to ---- in std::string|256_cv 2.78 % 2.91 % 10 +replace bb to ---- in std::string|512_mean 1534 ns 1521 ns 10 +replace bb to ---- in std::string|512_median 1522 ns 1517 ns 10 +replace bb to ---- in std::string|512_stddev 51.7 ns 59.7 ns 10 +replace bb to ---- in std::string|512_cv 3.37 % 3.93 % 10 +replace bb to ---- in std::string|1024_mean 3381 ns 3354 ns 10 +replace bb to ---- in std::string|1024_median 3379 ns 3369 ns 10 +replace bb to ---- in std::string|1024_stddev 92.1 ns 83.2 ns 10 +replace bb to ---- in std::string|1024_cv 2.72 % 2.48 % 10 +replace bb to ---- in std::string|2048_mean 8081 ns 8057 ns 10 +replace bb to ---- in std::string|2048_median 8100 ns 8022 ns 10 +replace bb to ---- in std::string|2048_stddev 97.1 ns 110 ns 10 +replace bb to ---- in std::string|2048_cv 1.20 % 1.37 % 10 +replace bb to ---- in lstringa<8>|64_mean 349 ns 346 ns 10 +replace bb to ---- in lstringa<8>|64_median 347 ns 345 ns 10 +replace bb to ---- in lstringa<8>|64_stddev 11.2 ns 12.2 ns 10 +replace bb to ---- in lstringa<8>|64_cv 3.21 % 3.54 % 10 +replace bb to ---- in lstringa<8>|256_mean 702 ns 696 ns 10 +replace bb to ---- in lstringa<8>|256_median 690 ns 684 ns 10 +replace bb to ---- in lstringa<8>|256_stddev 29.3 ns 28.2 ns 10 +replace bb to ---- in lstringa<8>|256_cv 4.18 % 4.06 % 10 +replace bb to ---- in lstringa<8>|512_mean 1187 ns 1183 ns 10 +replace bb to ---- in lstringa<8>|512_median 1180 ns 1172 ns 10 +replace bb to ---- in lstringa<8>|512_stddev 29.9 ns 42.0 ns 10 +replace bb to ---- in lstringa<8>|512_cv 2.52 % 3.55 % 10 +replace bb to ---- in lstringa<8>|1024_mean 2087 ns 2068 ns 10 +replace bb to ---- in lstringa<8>|1024_median 2075 ns 2063 ns 10 +replace bb to ---- in lstringa<8>|1024_stddev 38.1 ns 61.2 ns 10 +replace bb to ---- in lstringa<8>|1024_cv 1.82 % 2.96 % 10 +replace bb to ---- in lstringa<8>|2048_mean 4039 ns 3999 ns 10 +replace bb to ---- in lstringa<8>|2048_median 4012 ns 3990 ns 10 +replace bb to ---- in lstringa<8>|2048_stddev 145 ns 90.2 ns 10 +replace bb to ---- in lstringa<8>|2048_cv 3.58 % 2.25 % 10 +replace bb to ---- by init stringa|64_mean 230 ns 228 ns 10 +replace bb to ---- by init stringa|64_median 229 ns 225 ns 10 +replace bb to ---- by init stringa|64_stddev 7.53 ns 6.62 ns 10 +replace bb to ---- by init stringa|64_cv 3.27 % 2.90 % 10 +replace bb to ---- by init stringa|256_mean 573 ns 572 ns 10 +replace bb to ---- by init stringa|256_median 574 ns 578 ns 10 +replace bb to ---- by init stringa|256_stddev 10.1 ns 16.8 ns 10 +replace bb to ---- by init stringa|256_cv 1.77 % 2.94 % 10 +replace bb to ---- by init stringa|512_mean 1009 ns 1011 ns 10 +replace bb to ---- by init stringa|512_median 1006 ns 1004 ns 10 +replace bb to ---- by init stringa|512_stddev 13.1 ns 14.1 ns 10 +replace bb to ---- by init stringa|512_cv 1.30 % 1.40 % 10 +replace bb to ---- by init stringa|1024_mean 1988 ns 1963 ns 10 +replace bb to ---- by init stringa|1024_median 1918 ns 1925 ns 10 +replace bb to ---- by init stringa|1024_stddev 165 ns 127 ns 10 +replace bb to ---- by init stringa|1024_cv 8.31 % 6.47 % 10 +replace bb to ---- by init stringa|2048_mean 3790 ns 3775 ns 10 +replace bb to ---- by init stringa|2048_median 3702 ns 3706 ns 10 +replace bb to ---- by init stringa|2048_stddev 230 ns 184 ns 10 +replace bb to ---- by init stringa|2048_cv 6.07 % 4.87 % 10 +----- Replace All Str To Same Size ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +replace bb to -- in std::string|64_mean 218 ns 218 ns 10 +replace bb to -- in std::string|64_median 216 ns 215 ns 10 +replace bb to -- in std::string|64_stddev 8.42 ns 8.90 ns 10 +replace bb to -- in std::string|64_cv 3.85 % 4.08 % 10 +replace bb to -- in std::string|256_mean 539 ns 539 ns 10 +replace bb to -- in std::string|256_median 537 ns 537 ns 10 +replace bb to -- in std::string|256_stddev 10.6 ns 16.4 ns 10 +replace bb to -- in std::string|256_cv 1.97 % 3.04 % 10 +replace bb to -- in std::string|512_mean 979 ns 977 ns 10 +replace bb to -- in std::string|512_median 976 ns 973 ns 10 +replace bb to -- in std::string|512_stddev 20.3 ns 28.0 ns 10 +replace bb to -- in std::string|512_cv 2.07 % 2.86 % 10 +replace bb to -- in std::string|1024_mean 1885 ns 1873 ns 10 +replace bb to -- in std::string|1024_median 1840 ns 1814 ns 10 +replace bb to -- in std::string|1024_stddev 134 ns 148 ns 10 +replace bb to -- in std::string|1024_cv 7.09 % 7.91 % 10 +replace bb to -- in std::string|2048_mean 3576 ns 3560 ns 10 +replace bb to -- in std::string|2048_median 3558 ns 3530 ns 10 +replace bb to -- in std::string|2048_stddev 87.0 ns 97.1 ns 10 +replace bb to -- in std::string|2048_cv 2.43 % 2.73 % 10 +replace bb to -- in lstringa<8>|64_mean 202 ns 199 ns 10 +replace bb to -- in lstringa<8>|64_median 199 ns 201 ns 10 +replace bb to -- in lstringa<8>|64_stddev 10.2 ns 8.88 ns 10 +replace bb to -- in lstringa<8>|64_cv 5.05 % 4.47 % 10 +replace bb to -- in lstringa<8>|256_mean 470 ns 467 ns 10 +replace bb to -- in lstringa<8>|256_median 471 ns 471 ns 10 +replace bb to -- in lstringa<8>|256_stddev 11.5 ns 8.82 ns 10 +replace bb to -- in lstringa<8>|256_cv 2.45 % 1.89 % 10 +replace bb to -- in lstringa<8>|512_mean 816 ns 814 ns 10 +replace bb to -- in lstringa<8>|512_median 810 ns 802 ns 10 +replace bb to -- in lstringa<8>|512_stddev 20.9 ns 18.5 ns 10 +replace bb to -- in lstringa<8>|512_cv 2.56 % 2.27 % 10 +replace bb to -- in lstringa<8>|1024_mean 1515 ns 1504 ns 10 +replace bb to -- in lstringa<8>|1024_median 1506 ns 1507 ns 10 +replace bb to -- in lstringa<8>|1024_stddev 41.4 ns 43.0 ns 10 +replace bb to -- in lstringa<8>|1024_cv 2.73 % 2.86 % 10 +replace bb to -- in lstringa<8>|2048_mean 2909 ns 2875 ns 10 +replace bb to -- in lstringa<8>|2048_median 2897 ns 2856 ns 10 +replace bb to -- in lstringa<8>|2048_stddev 63.6 ns 57.7 ns 10 +replace bb to -- in lstringa<8>|2048_cv 2.19 % 2.01 % 10 +replace bb to -- by init stringa|64_mean 183 ns 181 ns 10 +replace bb to -- by init stringa|64_median 180 ns 180 ns 10 +replace bb to -- by init stringa|64_stddev 5.34 ns 5.44 ns 10 +replace bb to -- by init stringa|64_cv 2.92 % 3.00 % 10 +replace bb to -- by init stringa|256_mean 392 ns 384 ns 10 +replace bb to -- by init stringa|256_median 388 ns 381 ns 10 +replace bb to -- by init stringa|256_stddev 12.6 ns 14.8 ns 10 +replace bb to -- by init stringa|256_cv 3.21 % 3.87 % 10 +replace bb to -- by init stringa|512_mean 668 ns 657 ns 10 +replace bb to -- by init stringa|512_median 660 ns 663 ns 10 +replace bb to -- by init stringa|512_stddev 16.9 ns 14.4 ns 10 +replace bb to -- by init stringa|512_cv 2.53 % 2.18 % 10 +replace bb to -- by init stringa|1024_mean 1201 ns 1197 ns 10 +replace bb to -- by init stringa|1024_median 1201 ns 1200 ns 10 +replace bb to -- by init stringa|1024_stddev 21.6 ns 24.4 ns 10 +replace bb to -- by init stringa|1024_cv 1.80 % 2.04 % 10 +replace bb to -- by init stringa|2048_mean 2295 ns 2285 ns 10 +replace bb to -- by init stringa|2048_median 2275 ns 2295 ns 10 +replace bb to -- by init stringa|2048_stddev 50.8 ns 55.4 ns 10 +replace bb to -- by init stringa|2048_cv 2.21 % 2.43 % 10 +----- Hash Map insert and find ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +hashStrMapA emplace & find stringa;_mean 4237335 ns 4230925 ns 10 +hashStrMapA emplace & find stringa;_median 4253455 ns 4261364 ns 10 +hashStrMapA emplace & find stringa;_stddev 162581 ns 151627 ns 10 +hashStrMapA emplace & find stringa;_cv 3.84 % 3.58 % 10 +std::unordered_map emplace & find std::string;_mean 5468019 ns 5343750 ns 10 +std::unordered_map emplace & find std::string;_median 5365539 ns 5312500 ns 10 +std::unordered_map emplace & find std::string;_stddev 272590 ns 98821 ns 10 +std::unordered_map emplace & find std::string;_cv 4.99 % 1.85 % 10 +hashStrMapA emplace & find ssa;_mean 3990921 ns 3919344 ns 10 +hashStrMapA emplace & find ssa;_median 3971040 ns 3928073 ns 10 +hashStrMapA emplace & find ssa;_stddev 113397 ns 145193 ns 10 +hashStrMapA emplace & find ssa;_cv 2.84 % 3.70 % 10 +std::unordered_map emplace & find std::string_view;_mean 6304651 ns 6305804 ns 10 +std::unordered_map emplace & find std::string_view;_median 6263162 ns 6277902 ns 10 +std::unordered_map emplace & find std::string_view;_stddev 161063 ns 171495 ns 10 +std::unordered_map emplace & find std::string_view;_cv 2.55 % 2.72 % 10 +----- Build Full Func Name ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +Build func full name std::string;_mean 1660 ns 1638 ns 10 +Build func full name std::string;_median 1637 ns 1650 ns 10 +Build func full name std::string;_stddev 56.0 ns 25.9 ns 10 +Build func full name std::string;_cv 3.37 % 1.58 % 10 +Build func full name std::string 1;_mean 1747 ns 1737 ns 10 +Build func full name std::string 1;_median 1738 ns 1709 ns 10 +Build func full name std::string 1;_stddev 50.9 ns 51.5 ns 10 +Build func full name std::string 1;_cv 2.91 % 2.96 % 10 +Build func full name std::stream;_mean 9942 ns 9647 ns 10 +Build func full name std::stream;_median 9768 ns 9626 ns 10 +Build func full name std::stream;_stddev 436 ns 287 ns 10 +Build func full name std::stream;_cv 4.38 % 2.97 % 10 +Build func full name stringa;_mean 891 ns 872 ns 10 +Build func full name stringa;_median 879 ns 872 ns 10 +Build func full name stringa;_stddev 31.8 ns 16.4 ns 10 +Build func full name stringa;_cv 3.57 % 1.89 % 10 +Build func full name stringa 1;_mean 1007 ns 1001 ns 10 +Build func full name stringa 1;_median 998 ns 1001 ns 10 +Build func full name stringa 1;_stddev 33.0 ns 25.7 ns 10 +Build func full name stringa 1;_cv 3.28 % 2.57 % 10 diff --git a/bench/results/004-Xeon E5-2682 v4, WASM Chrome, Clang-21.txt b/bench/results/004-Xeon E5-2682 v4, WASM Chrome, Clang-21.txt new file mode 100644 index 0000000..ffd12b4 --- /dev/null +++ b/bench/results/004-Xeon E5-2682 v4, WASM Chrome, Clang-21.txt @@ -0,0 +1,783 @@ +Run on (32 X 2513.96 MHz CPU s) +Chrome 136.0.7103.114 webasm +-------------------------------------------------------------------------------------------------------------------------------------------------------- +Benchmark Time CPU Iterations +-------------------------------------------------------------------------------------------------------------------------------------------------------- +----- Create Empty Str ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e;_mean 3.47 ns 3.47 ns 10 +std::string e;_median 3.46 ns 3.46 ns 10 +std::string e;_stddev 0.077 ns 0.077 ns 10 +std::string e;_cv 2.22 % 2.22 % 10 +std::string_view e;_mean 3.68 ns 3.68 ns 10 +std::string_view e;_median 3.68 ns 3.68 ns 10 +std::string_view e;_stddev 0.025 ns 0.025 ns 10 +std::string_view e;_cv 0.67 % 0.67 % 10 +ssa e;_mean 2.14 ns 2.14 ns 10 +ssa e;_median 2.14 ns 2.14 ns 10 +ssa e;_stddev 0.022 ns 0.022 ns 10 +ssa e;_cv 1.01 % 1.01 % 10 +stringa e;_mean 3.66 ns 3.66 ns 10 +stringa e;_median 3.66 ns 3.66 ns 10 +stringa e;_stddev 0.070 ns 0.070 ns 10 +stringa e;_cv 1.91 % 1.91 % 10 +lstringa<20> e;_mean 3.10 ns 3.10 ns 10 +lstringa<20> e;_median 3.05 ns 3.05 ns 10 +lstringa<20> e;_stddev 0.112 ns 0.112 ns 10 +lstringa<20> e;_cv 3.63 % 3.63 % 10 +lstringa<40> e;_mean 3.10 ns 3.10 ns 10 +lstringa<40> e;_median 3.10 ns 3.10 ns 10 +lstringa<40> e;_stddev 0.080 ns 0.080 ns 10 +lstringa<40> e;_cv 2.56 % 2.56 % 10 +----- Create Str from short literal (9 symbols) --------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "Test text";_mean 4.95 ns 4.95 ns 10 +std::string e = "Test text";_median 4.93 ns 4.93 ns 10 +std::string e = "Test text";_stddev 0.074 ns 0.074 ns 10 +std::string e = "Test text";_cv 1.50 % 1.50 % 10 +std::string_view e = "Test text";_mean 2.22 ns 2.22 ns 10 +std::string_view e = "Test text";_median 2.22 ns 2.22 ns 10 +std::string_view e = "Test text";_stddev 0.024 ns 0.024 ns 10 +std::string_view e = "Test text";_cv 1.10 % 1.10 % 10 +ssa e = "Test text";_mean 2.18 ns 2.18 ns 10 +ssa e = "Test text";_median 2.18 ns 2.18 ns 10 +ssa e = "Test text";_stddev 0.021 ns 0.021 ns 10 +ssa e = "Test text";_cv 0.99 % 0.99 % 10 +stringa e = "Test text";_mean 4.69 ns 4.69 ns 10 +stringa e = "Test text";_median 4.67 ns 4.67 ns 10 +stringa e = "Test text";_stddev 0.087 ns 0.087 ns 10 +stringa e = "Test text";_cv 1.85 % 1.85 % 10 +lstringa<20> e = "Test text";_mean 6.54 ns 6.54 ns 10 +lstringa<20> e = "Test text";_median 6.54 ns 6.54 ns 10 +lstringa<20> e = "Test text";_stddev 0.109 ns 0.109 ns 10 +lstringa<20> e = "Test text";_cv 1.67 % 1.67 % 10 +lstringa<40> e = "Test text";_mean 4.02 ns 4.02 ns 10 +lstringa<40> e = "Test text";_median 4.01 ns 4.01 ns 10 +lstringa<40> e = "Test text";_stddev 0.090 ns 0.090 ns 10 +lstringa<40> e = "Test text";_cv 2.24 % 2.24 % 10 +----- Create Str from long literal (30 symbols) ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "123456789012345678901234567890";_mean 56.3 ns 56.3 ns 10 +std::string e = "123456789012345678901234567890";_median 55.8 ns 55.8 ns 10 +std::string e = "123456789012345678901234567890";_stddev 2.07 ns 2.07 ns 10 +std::string e = "123456789012345678901234567890";_cv 3.67 % 3.67 % 10 +std::string_view e = "123456789012345678901234567890";_mean 5.05 ns 5.05 ns 10 +std::string_view e = "123456789012345678901234567890";_median 5.06 ns 5.06 ns 10 +std::string_view e = "123456789012345678901234567890";_stddev 0.026 ns 0.026 ns 10 +std::string_view e = "123456789012345678901234567890";_cv 0.52 % 0.52 % 10 +ssa e = "123456789012345678901234567890";_mean 2.18 ns 2.18 ns 10 +ssa e = "123456789012345678901234567890";_median 2.17 ns 2.17 ns 10 +ssa e = "123456789012345678901234567890";_stddev 0.031 ns 0.031 ns 10 +ssa e = "123456789012345678901234567890";_cv 1.40 % 1.40 % 10 +stringa e = "123456789012345678901234567890";_mean 5.33 ns 5.33 ns 10 +stringa e = "123456789012345678901234567890";_median 5.32 ns 5.32 ns 10 +stringa e = "123456789012345678901234567890";_stddev 0.033 ns 0.033 ns 10 +stringa e = "123456789012345678901234567890";_cv 0.63 % 0.63 % 10 +lstringa<20> e = "123456789012345678901234567890";_mean 59.7 ns 59.7 ns 10 +lstringa<20> e = "123456789012345678901234567890";_median 59.2 ns 59.2 ns 10 +lstringa<20> e = "123456789012345678901234567890";_stddev 1.30 ns 1.30 ns 10 +lstringa<20> e = "123456789012345678901234567890";_cv 2.18 % 2.18 % 10 +lstringa<40> e = "123456789012345678901234567890";_mean 6.28 ns 6.28 ns 10 +lstringa<40> e = "123456789012345678901234567890";_median 6.20 ns 6.20 ns 10 +lstringa<40> e = "123456789012345678901234567890";_stddev 0.202 ns 0.202 ns 10 +lstringa<40> e = "123456789012345678901234567890";_cv 3.21 % 3.21 % 10 +----- Create copy of Str with 9 symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "Test text"; auto c{e};_mean 5.67 ns 5.67 ns 10 +std::string e = "Test text"; auto c{e};_median 5.66 ns 5.66 ns 10 +std::string e = "Test text"; auto c{e};_stddev 0.127 ns 0.127 ns 10 +std::string e = "Test text"; auto c{e};_cv 2.24 % 2.24 % 10 +std::string_view e = "Test text"; auto c{e};_mean 5.04 ns 5.04 ns 10 +std::string_view e = "Test text"; auto c{e};_median 5.03 ns 5.03 ns 10 +std::string_view e = "Test text"; auto c{e};_stddev 0.009 ns 0.009 ns 10 +std::string_view e = "Test text"; auto c{e};_cv 0.18 % 0.18 % 10 +ssa e = "Test text"; auto c{e};_mean 5.02 ns 5.02 ns 10 +ssa e = "Test text"; auto c{e};_median 5.02 ns 5.02 ns 10 +ssa e = "Test text"; auto c{e};_stddev 0.015 ns 0.015 ns 10 +ssa e = "Test text"; auto c{e};_cv 0.31 % 0.31 % 10 +stringa e = "Test text"; auto c{e};_mean 4.81 ns 4.81 ns 10 +stringa e = "Test text"; auto c{e};_median 4.80 ns 4.80 ns 10 +stringa e = "Test text"; auto c{e};_stddev 0.075 ns 0.075 ns 10 +stringa e = "Test text"; auto c{e};_cv 1.55 % 1.55 % 10 +lstringa<20> e = "Test text"; auto c{e};_mean 15.8 ns 15.8 ns 10 +lstringa<20> e = "Test text"; auto c{e};_median 15.5 ns 15.5 ns 10 +lstringa<20> e = "Test text"; auto c{e};_stddev 0.819 ns 0.819 ns 10 +lstringa<20> e = "Test text"; auto c{e};_cv 5.19 % 5.19 % 10 +lstringa<40> e = "Test text"; auto c{e};_mean 15.7 ns 15.7 ns 10 +lstringa<40> e = "Test text"; auto c{e};_median 15.7 ns 15.7 ns 10 +lstringa<40> e = "Test text"; auto c{e};_stddev 0.536 ns 0.536 ns 10 +lstringa<40> e = "Test text"; auto c{e};_cv 3.41 % 3.41 % 10 +----- Create copy of Str with 30 symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string e = "123456789012345678901234567890"; auto c{e};_mean 116 ns 116 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_median 113 ns 113 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_stddev 5.88 ns 5.88 ns 10 +std::string e = "123456789012345678901234567890"; auto c{e};_cv 5.06 % 5.06 % 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_mean 5.04 ns 5.04 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_median 5.03 ns 5.03 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_stddev 0.038 ns 0.038 ns 10 +std::string_view e = "123456789012345678901234567890"; auto c{e};_cv 0.75 % 0.75 % 10 +ssa e = "123456789012345678901234567890"; auto c{e};_mean 2.20 ns 2.20 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_median 2.19 ns 2.19 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_stddev 0.038 ns 0.038 ns 10 +ssa e = "123456789012345678901234567890"; auto c{e};_cv 1.73 % 1.73 % 10 +stringa e = "123456789012345678901234567890"; auto c{e};_mean 5.36 ns 5.36 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_median 5.36 ns 5.36 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_stddev 0.068 ns 0.068 ns 10 +stringa e = "123456789012345678901234567890"; auto c{e};_cv 1.28 % 1.28 % 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_mean 67.1 ns 67.1 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_median 67.0 ns 67.0 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_stddev 1.65 ns 1.65 ns 10 +lstringa<20> e = "123456789012345678901234567890"; auto c{e};_cv 2.46 % 2.46 % 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_mean 15.5 ns 15.5 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_median 15.5 ns 15.5 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_stddev 0.607 ns 0.607 ns 10 +lstringa<40> e = "123456789012345678901234567890"; auto c{e};_cv 3.90 % 3.90 % 10 +----- Find 9 symbols text in end of 99 symbols text ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string::find;_mean 141 ns 141 ns 10 +std::string::find;_median 138 ns 138 ns 10 +std::string::find;_stddev 7.07 ns 7.07 ns 10 +std::string::find;_cv 5.00 % 5.00 % 10 +std::string_view::find;_mean 134 ns 134 ns 10 +std::string_view::find;_median 133 ns 133 ns 10 +std::string_view::find;_stddev 4.94 ns 4.94 ns 10 +std::string_view::find;_cv 3.68 % 3.68 % 10 +ssa::find;_mean 101 ns 101 ns 10 +ssa::find;_median 102 ns 102 ns 10 +ssa::find;_stddev 4.82 ns 4.82 ns 10 +ssa::find;_cv 4.75 % 4.75 % 10 +stringa::find;_mean 102 ns 102 ns 10 +stringa::find;_median 101 ns 101 ns 10 +stringa::find;_stddev 2.09 ns 2.09 ns 10 +stringa::find;_cv 2.06 % 2.06 % 10 +lstringa<20>::find;_mean 100 ns 100 ns 10 +lstringa<20>::find;_median 100 ns 100 ns 10 +lstringa<20>::find;_stddev 2.47 ns 2.47 ns 10 +lstringa<20>::find;_cv 2.46 % 2.46 % 10 +lstringa<40>::find;_mean 102 ns 102 ns 10 +lstringa<40>::find;_median 102 ns 102 ns 10 +lstringa<40>::find;_stddev 2.47 ns 2.47 ns 10 +lstringa<40>::find;_cv 2.42 % 2.42 % 10 +------- Copy not literal Str with N symbols ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string copy{str_with_len_N};/15_mean 117 ns 117 ns 10 +std::string copy{str_with_len_N};/15_median 118 ns 118 ns 10 +std::string copy{str_with_len_N};/15_stddev 2.87 ns 2.87 ns 10 +std::string copy{str_with_len_N};/15_cv 2.45 % 2.45 % 10 +std::string copy{str_with_len_N};/16_mean 120 ns 120 ns 10 +std::string copy{str_with_len_N};/16_median 119 ns 119 ns 10 +std::string copy{str_with_len_N};/16_stddev 4.25 ns 4.25 ns 10 +std::string copy{str_with_len_N};/16_cv 3.54 % 3.54 % 10 +std::string copy{str_with_len_N};/23_mean 119 ns 119 ns 10 +std::string copy{str_with_len_N};/23_median 119 ns 119 ns 10 +std::string copy{str_with_len_N};/23_stddev 4.81 ns 4.81 ns 10 +std::string copy{str_with_len_N};/23_cv 4.03 % 4.03 % 10 +std::string copy{str_with_len_N};/24_mean 120 ns 120 ns 10 +std::string copy{str_with_len_N};/24_median 117 ns 117 ns 10 +std::string copy{str_with_len_N};/24_stddev 6.96 ns 6.96 ns 10 +std::string copy{str_with_len_N};/24_cv 5.78 % 5.78 % 10 +std::string copy{str_with_len_N};/32_mean 124 ns 124 ns 10 +std::string copy{str_with_len_N};/32_median 125 ns 125 ns 10 +std::string copy{str_with_len_N};/32_stddev 4.17 ns 4.17 ns 10 +std::string copy{str_with_len_N};/32_cv 3.37 % 3.37 % 10 +std::string copy{str_with_len_N};/64_mean 125 ns 125 ns 10 +std::string copy{str_with_len_N};/64_median 125 ns 125 ns 10 +std::string copy{str_with_len_N};/64_stddev 5.21 ns 5.21 ns 10 +std::string copy{str_with_len_N};/64_cv 4.16 % 4.16 % 10 +std::string copy{str_with_len_N};/128_mean 122 ns 122 ns 10 +std::string copy{str_with_len_N};/128_median 121 ns 121 ns 10 +std::string copy{str_with_len_N};/128_stddev 5.21 ns 5.21 ns 10 +std::string copy{str_with_len_N};/128_cv 4.27 % 4.27 % 10 +std::string copy{str_with_len_N};/256_mean 146 ns 146 ns 10 +std::string copy{str_with_len_N};/256_median 152 ns 152 ns 10 +std::string copy{str_with_len_N};/256_stddev 17.4 ns 17.4 ns 10 +std::string copy{str_with_len_N};/256_cv 11.94 % 11.94 % 10 +std::string copy{str_with_len_N};/512_mean 163 ns 163 ns 10 +std::string copy{str_with_len_N};/512_median 168 ns 168 ns 10 +std::string copy{str_with_len_N};/512_stddev 37.9 ns 37.9 ns 10 +std::string copy{str_with_len_N};/512_cv 23.21 % 23.21 % 10 +std::string copy{str_with_len_N};/1024_mean 148 ns 148 ns 10 +std::string copy{str_with_len_N};/1024_median 142 ns 142 ns 10 +std::string copy{str_with_len_N};/1024_stddev 23.5 ns 23.5 ns 10 +std::string copy{str_with_len_N};/1024_cv 15.86 % 15.86 % 10 +std::string copy{str_with_len_N};/2048_mean 165 ns 165 ns 10 +std::string copy{str_with_len_N};/2048_median 165 ns 165 ns 10 +std::string copy{str_with_len_N};/2048_stddev 8.09 ns 8.09 ns 10 +std::string copy{str_with_len_N};/2048_cv 4.92 % 4.92 % 10 +std::string copy{str_with_len_N};/4096_mean 204 ns 204 ns 10 +std::string copy{str_with_len_N};/4096_median 203 ns 203 ns 10 +std::string copy{str_with_len_N};/4096_stddev 9.70 ns 9.70 ns 10 +std::string copy{str_with_len_N};/4096_cv 4.76 % 4.76 % 10 +stringa copy{str_with_len_N};/15_mean 4.84 ns 4.84 ns 10 +stringa copy{str_with_len_N};/15_median 4.80 ns 4.80 ns 10 +stringa copy{str_with_len_N};/15_stddev 0.112 ns 0.112 ns 10 +stringa copy{str_with_len_N};/15_cv 2.31 % 2.31 % 10 +stringa copy{str_with_len_N};/16_mean 10.3 ns 10.3 ns 10 +stringa copy{str_with_len_N};/16_median 10.1 ns 10.1 ns 10 +stringa copy{str_with_len_N};/16_stddev 0.343 ns 0.343 ns 10 +stringa copy{str_with_len_N};/16_cv 3.35 % 3.35 % 10 +stringa copy{str_with_len_N};/23_mean 10.1 ns 10.1 ns 10 +stringa copy{str_with_len_N};/23_median 10.2 ns 10.2 ns 10 +stringa copy{str_with_len_N};/23_stddev 0.210 ns 0.210 ns 10 +stringa copy{str_with_len_N};/23_cv 2.07 % 2.07 % 10 +stringa copy{str_with_len_N};/24_mean 10.2 ns 10.2 ns 10 +stringa copy{str_with_len_N};/24_median 10.2 ns 10.2 ns 10 +stringa copy{str_with_len_N};/24_stddev 0.244 ns 0.244 ns 10 +stringa copy{str_with_len_N};/24_cv 2.40 % 2.40 % 10 +stringa copy{str_with_len_N};/32_mean 10.2 ns 10.2 ns 10 +stringa copy{str_with_len_N};/32_median 10.1 ns 10.1 ns 10 +stringa copy{str_with_len_N};/32_stddev 0.203 ns 0.204 ns 10 +stringa copy{str_with_len_N};/32_cv 2.00 % 2.00 % 10 +stringa copy{str_with_len_N};/64_mean 10.0 ns 10.0 ns 10 +stringa copy{str_with_len_N};/64_median 10.0 ns 10.0 ns 10 +stringa copy{str_with_len_N};/64_stddev 0.134 ns 0.134 ns 10 +stringa copy{str_with_len_N};/64_cv 1.34 % 1.34 % 10 +stringa copy{str_with_len_N};/128_mean 10.1 ns 10.1 ns 10 +stringa copy{str_with_len_N};/128_median 10.1 ns 10.1 ns 10 +stringa copy{str_with_len_N};/128_stddev 0.171 ns 0.171 ns 10 +stringa copy{str_with_len_N};/128_cv 1.70 % 1.71 % 10 +stringa copy{str_with_len_N};/256_mean 10.1 ns 10.1 ns 10 +stringa copy{str_with_len_N};/256_median 10.1 ns 10.1 ns 10 +stringa copy{str_with_len_N};/256_stddev 0.138 ns 0.138 ns 10 +stringa copy{str_with_len_N};/256_cv 1.37 % 1.37 % 10 +stringa copy{str_with_len_N};/512_mean 10.1 ns 10.1 ns 10 +stringa copy{str_with_len_N};/512_median 10.0 ns 10.0 ns 10 +stringa copy{str_with_len_N};/512_stddev 0.187 ns 0.187 ns 10 +stringa copy{str_with_len_N};/512_cv 1.85 % 1.85 % 10 +stringa copy{str_with_len_N};/1024_mean 10.0 ns 10.0 ns 10 +stringa copy{str_with_len_N};/1024_median 9.97 ns 9.97 ns 10 +stringa copy{str_with_len_N};/1024_stddev 0.168 ns 0.168 ns 10 +stringa copy{str_with_len_N};/1024_cv 1.68 % 1.68 % 10 +stringa copy{str_with_len_N};/2048_mean 10.0 ns 10.0 ns 10 +stringa copy{str_with_len_N};/2048_median 10.0 ns 10.0 ns 10 +stringa copy{str_with_len_N};/2048_stddev 0.121 ns 0.121 ns 10 +stringa copy{str_with_len_N};/2048_cv 1.21 % 1.21 % 10 +stringa copy{str_with_len_N};/4096_mean 10.1 ns 10.1 ns 10 +stringa copy{str_with_len_N};/4096_median 10.1 ns 10.1 ns 10 +stringa copy{str_with_len_N};/4096_stddev 0.091 ns 0.091 ns 10 +stringa copy{str_with_len_N};/4096_cv 0.90 % 0.90 % 10 +lstringa<16> copy{str_with_len_N};/15_mean 15.7 ns 15.7 ns 10 +lstringa<16> copy{str_with_len_N};/15_median 15.8 ns 15.8 ns 10 +lstringa<16> copy{str_with_len_N};/15_stddev 0.435 ns 0.435 ns 10 +lstringa<16> copy{str_with_len_N};/15_cv 2.78 % 2.78 % 10 +lstringa<16> copy{str_with_len_N};/16_mean 16.1 ns 16.1 ns 10 +lstringa<16> copy{str_with_len_N};/16_median 16.1 ns 16.1 ns 10 +lstringa<16> copy{str_with_len_N};/16_stddev 0.768 ns 0.768 ns 10 +lstringa<16> copy{str_with_len_N};/16_cv 4.76 % 4.76 % 10 +lstringa<16> copy{str_with_len_N};/23_mean 75.4 ns 75.4 ns 10 +lstringa<16> copy{str_with_len_N};/23_median 75.3 ns 75.3 ns 10 +lstringa<16> copy{str_with_len_N};/23_stddev 3.08 ns 3.08 ns 10 +lstringa<16> copy{str_with_len_N};/23_cv 4.08 % 4.08 % 10 +lstringa<16> copy{str_with_len_N};/24_mean 76.2 ns 76.2 ns 10 +lstringa<16> copy{str_with_len_N};/24_median 75.6 ns 75.6 ns 10 +lstringa<16> copy{str_with_len_N};/24_stddev 4.31 ns 4.31 ns 10 +lstringa<16> copy{str_with_len_N};/24_cv 5.66 % 5.66 % 10 +lstringa<16> copy{str_with_len_N};/32_mean 82.1 ns 82.1 ns 10 +lstringa<16> copy{str_with_len_N};/32_median 82.8 ns 82.8 ns 10 +lstringa<16> copy{str_with_len_N};/32_stddev 5.50 ns 5.50 ns 10 +lstringa<16> copy{str_with_len_N};/32_cv 6.70 % 6.70 % 10 +lstringa<16> copy{str_with_len_N};/64_mean 78.1 ns 78.1 ns 10 +lstringa<16> copy{str_with_len_N};/64_median 78.0 ns 78.0 ns 10 +lstringa<16> copy{str_with_len_N};/64_stddev 2.56 ns 2.56 ns 10 +lstringa<16> copy{str_with_len_N};/64_cv 3.27 % 3.27 % 10 +lstringa<16> copy{str_with_len_N};/128_mean 79.2 ns 79.2 ns 10 +lstringa<16> copy{str_with_len_N};/128_median 77.8 ns 77.8 ns 10 +lstringa<16> copy{str_with_len_N};/128_stddev 3.51 ns 3.51 ns 10 +lstringa<16> copy{str_with_len_N};/128_cv 4.44 % 4.44 % 10 +lstringa<16> copy{str_with_len_N};/256_mean 103 ns 103 ns 10 +lstringa<16> copy{str_with_len_N};/256_median 110 ns 110 ns 10 +lstringa<16> copy{str_with_len_N};/256_stddev 16.2 ns 16.2 ns 10 +lstringa<16> copy{str_with_len_N};/256_cv 15.73 % 15.73 % 10 +lstringa<16> copy{str_with_len_N};/512_mean 121 ns 121 ns 10 +lstringa<16> copy{str_with_len_N};/512_median 120 ns 120 ns 10 +lstringa<16> copy{str_with_len_N};/512_stddev 39.3 ns 39.3 ns 10 +lstringa<16> copy{str_with_len_N};/512_cv 32.53 % 32.53 % 10 +lstringa<16> copy{str_with_len_N};/1024_mean 107 ns 107 ns 10 +lstringa<16> copy{str_with_len_N};/1024_median 103 ns 103 ns 10 +lstringa<16> copy{str_with_len_N};/1024_stddev 25.3 ns 25.3 ns 10 +lstringa<16> copy{str_with_len_N};/1024_cv 23.61 % 23.61 % 10 +lstringa<16> copy{str_with_len_N};/2048_mean 123 ns 123 ns 10 +lstringa<16> copy{str_with_len_N};/2048_median 122 ns 122 ns 10 +lstringa<16> copy{str_with_len_N};/2048_stddev 7.32 ns 7.32 ns 10 +lstringa<16> copy{str_with_len_N};/2048_cv 5.96 % 5.96 % 10 +lstringa<16> copy{str_with_len_N};/4096_mean 160 ns 160 ns 10 +lstringa<16> copy{str_with_len_N};/4096_median 161 ns 161 ns 10 +lstringa<16> copy{str_with_len_N};/4096_stddev 13.4 ns 13.4 ns 10 +lstringa<16> copy{str_with_len_N};/4096_cv 8.38 % 8.38 % 10 +lstringa<512> copy{str_with_len_N};/15_mean 15.3 ns 15.3 ns 10 +lstringa<512> copy{str_with_len_N};/15_median 15.2 ns 15.2 ns 10 +lstringa<512> copy{str_with_len_N};/15_stddev 0.277 ns 0.277 ns 10 +lstringa<512> copy{str_with_len_N};/15_cv 1.82 % 1.82 % 10 +lstringa<512> copy{str_with_len_N};/16_mean 15.1 ns 15.1 ns 10 +lstringa<512> copy{str_with_len_N};/16_median 15.2 ns 15.2 ns 10 +lstringa<512> copy{str_with_len_N};/16_stddev 0.358 ns 0.358 ns 10 +lstringa<512> copy{str_with_len_N};/16_cv 2.37 % 2.37 % 10 +lstringa<512> copy{str_with_len_N};/23_mean 15.6 ns 15.6 ns 10 +lstringa<512> copy{str_with_len_N};/23_median 15.6 ns 15.6 ns 10 +lstringa<512> copy{str_with_len_N};/23_stddev 0.607 ns 0.607 ns 10 +lstringa<512> copy{str_with_len_N};/23_cv 3.89 % 3.89 % 10 +lstringa<512> copy{str_with_len_N};/24_mean 15.3 ns 15.3 ns 10 +lstringa<512> copy{str_with_len_N};/24_median 15.3 ns 15.3 ns 10 +lstringa<512> copy{str_with_len_N};/24_stddev 0.619 ns 0.619 ns 10 +lstringa<512> copy{str_with_len_N};/24_cv 4.05 % 4.05 % 10 +lstringa<512> copy{str_with_len_N};/32_mean 17.2 ns 17.2 ns 10 +lstringa<512> copy{str_with_len_N};/32_median 17.1 ns 17.1 ns 10 +lstringa<512> copy{str_with_len_N};/32_stddev 0.672 ns 0.672 ns 10 +lstringa<512> copy{str_with_len_N};/32_cv 3.90 % 3.90 % 10 +lstringa<512> copy{str_with_len_N};/64_mean 18.3 ns 18.3 ns 10 +lstringa<512> copy{str_with_len_N};/64_median 18.1 ns 18.1 ns 10 +lstringa<512> copy{str_with_len_N};/64_stddev 0.938 ns 0.938 ns 10 +lstringa<512> copy{str_with_len_N};/64_cv 5.14 % 5.14 % 10 +lstringa<512> copy{str_with_len_N};/128_mean 19.1 ns 19.1 ns 10 +lstringa<512> copy{str_with_len_N};/128_median 19.1 ns 19.1 ns 10 +lstringa<512> copy{str_with_len_N};/128_stddev 0.733 ns 0.733 ns 10 +lstringa<512> copy{str_with_len_N};/128_cv 3.84 % 3.84 % 10 +lstringa<512> copy{str_with_len_N};/256_mean 32.3 ns 32.3 ns 10 +lstringa<512> copy{str_with_len_N};/256_median 32.3 ns 32.3 ns 10 +lstringa<512> copy{str_with_len_N};/256_stddev 0.534 ns 0.534 ns 10 +lstringa<512> copy{str_with_len_N};/256_cv 1.65 % 1.65 % 10 +lstringa<512> copy{str_with_len_N};/512_mean 33.8 ns 33.8 ns 10 +lstringa<512> copy{str_with_len_N};/512_median 33.7 ns 33.7 ns 10 +lstringa<512> copy{str_with_len_N};/512_stddev 0.661 ns 0.661 ns 10 +lstringa<512> copy{str_with_len_N};/512_cv 1.95 % 1.95 % 10 +lstringa<512> copy{str_with_len_N};/1024_mean 106 ns 106 ns 10 +lstringa<512> copy{str_with_len_N};/1024_median 101 ns 101 ns 10 +lstringa<512> copy{str_with_len_N};/1024_stddev 26.1 ns 26.1 ns 10 +lstringa<512> copy{str_with_len_N};/1024_cv 24.65 % 24.65 % 10 +lstringa<512> copy{str_with_len_N};/2048_mean 119 ns 119 ns 10 +lstringa<512> copy{str_with_len_N};/2048_median 119 ns 119 ns 10 +lstringa<512> copy{str_with_len_N};/2048_stddev 6.93 ns 6.93 ns 10 +lstringa<512> copy{str_with_len_N};/2048_cv 5.81 % 5.81 % 10 +lstringa<512> copy{str_with_len_N};/4096_mean 162 ns 162 ns 10 +lstringa<512> copy{str_with_len_N};/4096_median 163 ns 163 ns 10 +lstringa<512> copy{str_with_len_N};/4096_stddev 10.0 ns 10.0 ns 10 +lstringa<512> copy{str_with_len_N};/4096_cv 6.19 % 6.19 % 10 +----- Convert to int '1234567' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_mean 205 ns 205 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_median 206 ns 206 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_stddev 6.93 ns 6.93 ns 10 +std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);_cv 3.39 % 3.39 % 10 +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10); ERROR OCCURRED: 'not implemented' +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10); ERROR OCCURRED: 'not implemented' +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10); ERROR OCCURRED: 'not implemented' +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10); ERROR OCCURRED: 'not implemented' +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10); ERROR OCCURRED: 'not implemented' +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10); ERROR OCCURRED: 'not implemented' +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10); ERROR OCCURRED: 'not implemented' +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10); ERROR OCCURRED: 'not implemented' +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10); ERROR OCCURRED: 'not implemented' +std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10); ERROR OCCURRED: 'not implemented' +stringa s = "123456789"; int res = s.to_int_mean 55.2 ns 55.2 ns 10 +stringa s = "123456789"; int res = s.to_int_median 54.5 ns 54.5 ns 10 +stringa s = "123456789"; int res = s.to_int_stddev 1.79 ns 1.79 ns 10 +stringa s = "123456789"; int res = s.to_int_cv 3.25 % 3.25 % 10 +ssa s = "123456789"; int res = s.to_int_mean 51.0 ns 51.0 ns 10 +ssa s = "123456789"; int res = s.to_int_median 51.1 ns 51.1 ns 10 +ssa s = "123456789"; int res = s.to_int_stddev 1.67 ns 1.67 ns 10 +ssa s = "123456789"; int res = s.to_int_cv 3.27 % 3.27 % 10 +lstringa<20> s = "123456789"; int res = s.to_int_mean 52.1 ns 52.1 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_median 51.3 ns 51.3 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_stddev 1.94 ns 1.94 ns 10 +lstringa<20> s = "123456789"; int res = s.to_int_cv 3.73 % 3.73 % 10 +----- Convert to unsigned 'abcDef' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_mean 149 ns 149 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_median 149 ns 149 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_stddev 3.19 ns 3.19 ns 10 +std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);_cv 2.14 % 2.14 % 10 +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16); ERROR OCCURRED: 'not implemented' +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16); ERROR OCCURRED: 'not implemented' +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16); ERROR OCCURRED: 'not implemented' +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16); ERROR OCCURRED: 'not implemented' +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16); ERROR OCCURRED: 'not implemented' +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16); ERROR OCCURRED: 'not implemented' +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16); ERROR OCCURRED: 'not implemented' +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16); ERROR OCCURRED: 'not implemented' +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16); ERROR OCCURRED: 'not implemented' +std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16); ERROR OCCURRED: 'not implemented' +stringa s = "abcDef"; int res = s.to_int_mean 51.8 ns 51.8 ns 10 +stringa s = "abcDef"; int res = s.to_int_median 51.5 ns 51.5 ns 10 +stringa s = "abcDef"; int res = s.to_int_stddev 0.900 ns 0.900 ns 10 +stringa s = "abcDef"; int res = s.to_int_cv 1.74 % 1.74 % 10 +ssa s = "abcDef"; int res = s.to_int_mean 50.0 ns 50.0 ns 10 +ssa s = "abcDef"; int res = s.to_int_median 50.1 ns 50.1 ns 10 +ssa s = "abcDef"; int res = s.to_int_stddev 0.773 ns 0.773 ns 10 +ssa s = "abcDef"; int res = s.to_int_cv 1.55 % 1.55 % 10 +lstringa<20> s = "abcDef"; int res = s.to_int_mean 51.4 ns 51.4 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_median 50.8 ns 50.8 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_stddev 1.46 ns 1.46 ns 10 +lstringa<20> s = "abcDef"; int res = s.to_int_cv 2.84 % 2.84 % 10 +----- Convert to int ' 1234567' ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_mean 216 ns 216 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_median 215 ns 215 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_stddev 9.26 ns 9.26 ns 10 +std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);_cv 4.28 % 4.28 % 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_mean 74.8 ns 74.8 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_median 75.4 ns 75.4 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_stddev 2.69 ns 2.69 ns 10 +stringa s = " 123456789"; int res = s.to_int; // Check overflow_cv 3.60 % 3.60 % 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_mean 51.3 ns 51.3 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_median 51.3 ns 51.3 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_stddev 0.921 ns 0.921 ns 10 +ssa s = " 123456789"; int res = s.to_int; // No check overflow_cv 1.79 % 1.79 % 10 +-- Append const literal of 16 bytes 64 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << "abbaabbaabbaabba";_mean 11603 ns 11603 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_median 11482 ns 11482 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_stddev 292 ns 292 ns 10 +std::stringstream str; ... str << "abbaabbaabbaabba";_cv 2.51 % 2.51 % 10 +std::string str; ... str += "abbaabbaabbaabba";_mean 1138 ns 1138 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_median 1122 ns 1122 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_stddev 58.6 ns 58.6 ns 10 +std::string str; ... str += "abbaabbaabbaabba";_cv 5.15 % 5.15 % 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_mean 1204 ns 1204 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_median 1191 ns 1191 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_stddev 54.3 ns 54.3 ns 10 +lstringa<8> str; ... str += "abbaabbaabbaabba";_cv 4.51 % 4.51 % 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_mean 873 ns 873 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_median 871 ns 871 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_stddev 60.7 ns 60.7 ns 10 +lstringa<128> str; ... str += "abbaabbaabbaabba";_cv 6.95 % 6.95 % 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_mean 640 ns 640 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_median 638 ns 638 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_stddev 38.9 ns 38.9 ns 10 +lstringa<512> str; ... str += "abbaabbaabbaabba";_cv 6.08 % 6.08 % 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_mean 498 ns 498 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_median 497 ns 497 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_stddev 9.13 ns 9.13 ns 10 +lstringa<1024> str; ... str += "abbaabbaabbaabba";_cv 1.83 % 1.83 % 10 +-- Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_mean 11698 ns 11698 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_median 11738 ns 11738 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_stddev 210 ns 210 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba";_cv 1.80 % 1.80 % 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_mean 4015 ns 4015 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_median 4012 ns 4012 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_stddev 170 ns 170 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba";_cv 4.23 % 4.23 % 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_mean 1435 ns 1435 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_median 1436 ns 1436 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_stddev 35.8 ns 35.8 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";_cv 2.49 % 2.49 % 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_mean 1128 ns 1128 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_median 1147 ns 1147 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_stddev 69.6 ns 69.6 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";_cv 6.17 % 6.17 % 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_mean 858 ns 858 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_median 846 ns 846 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_stddev 40.9 ns 40.9 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";_cv 4.76 % 4.76 % 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_mean 730 ns 730 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_median 724 ns 724 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_stddev 22.2 ns 22.2 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";_cv 3.03 % 3.03 % 10 +-- Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_mean 581542 ns 581546 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_median 576314 ns 576319 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_stddev 14331 ns 14332 ns 10 +std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times_cv 2.46 % 2.46 % 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 207680 ns 207682 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 209032 ns 209032 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 7880 ns 7881 ns 10 +std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 3.79 % 3.79 % 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 52577 ns 52578 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 51856 ns 51856 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 1859 ns 1859 ns 10 +lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 3.53 % 3.53 % 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 49889 ns 49889 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 49640 ns 49640 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 922 ns 922 ns 10 +lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 1.85 % 1.85 % 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 50097 ns 50097 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 50166 ns 50166 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 997 ns 997 ns 10 +lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 1.99 % 1.99 % 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_mean 49930 ns 49930 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_median 49358 ns 49359 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_stddev 1206 ns 1206 ns 10 +lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times_cv 2.42 % 2.42 % 10 +-- Append 2 string of 16 bytes 32 times, 1024 total length --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; ... str << str_var1 << str_var2;_mean 11739 ns 11739 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_median 11709 ns 11709 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_stddev 342 ns 342 ns 10 +std::stringstream str; ... str << str_var1 << str_var2;_cv 2.91 % 2.91 % 10 +std::string str; ... str += str_var1 + str_var2;_mean 4587 ns 4587 ns 10 +std::string str; ... str += str_var1 + str_var2;_median 4642 ns 4642 ns 10 +std::string str; ... str += str_var1 + str_var2;_stddev 172 ns 172 ns 10 +std::string str; ... str += str_var1 + str_var2;_cv 3.75 % 3.75 % 10 +lstringa<16> str; ... str += str_var1 + str_var2;_mean 1593 ns 1593 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_median 1590 ns 1590 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_stddev 43.9 ns 43.9 ns 10 +lstringa<16> str; ... str += str_var1 + str_var2;_cv 2.75 % 2.75 % 10 +lstringa<128> str; ... str += str_var1 + str_var2;_mean 1343 ns 1343 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_median 1326 ns 1326 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_stddev 62.5 ns 62.5 ns 10 +lstringa<128> str; ... str += str_var1 + str_var2;_cv 4.65 % 4.65 % 10 +lstringa<512> str; ... str += str_var1 + str_var2;_mean 1057 ns 1057 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_median 1058 ns 1058 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_stddev 38.9 ns 38.9 ns 10 +lstringa<512> str; ... str += str_var1 + str_var2;_cv 3.68 % 3.68 % 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_mean 929 ns 929 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_median 925 ns 925 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_stddev 22.0 ns 21.9 ns 10 +lstringa<1024> str; ... str += str_var1 + str_var2;_cv 2.36 % 2.36 % 10 +-- Append text, number, text --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::stringstream str; str << "test = " << k << " times";_mean 19990 ns 19990 ns 10 +std::stringstream str; str << "test = " << k << " times";_median 19963 ns 19963 ns 10 +std::stringstream str; str << "test = " << k << " times";_stddev 939 ns 939 ns 10 +std::stringstream str; str << "test = " << k << " times";_cv 4.70 % 4.70 % 10 +std::string str = "test = " + std::to_string(k) + " times";_mean 3781 ns 3781 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_median 3755 ns 3755 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_stddev 158 ns 158 ns 10 +std::string str = "test = " + std::to_string(k) + " times";_cv 4.19 % 4.19 % 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_mean 8018 ns 8018 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_median 7947 ns 7947 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_stddev 213 ns 213 ns 10 +char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;_cv 2.66 % 2.66 % 10 +std::string str = std::format("test = {} times", k);_mean 5058 ns 5058 ns 10 +std::string str = std::format("test = {} times", k);_median 5013 ns 5013 ns 10 +std::string str = std::format("test = {} times", k);_stddev 252 ns 252 ns 10 +std::string str = std::format("test = {} times", k);_cv 4.98 % 4.98 % 10 +lstringa<8> str; str.format("test = {} times", k);_mean 7141 ns 7141 ns 10 +lstringa<8> str; str.format("test = {} times", k);_median 7164 ns 7164 ns 10 +lstringa<8> str; str.format("test = {} times", k);_stddev 186 ns 186 ns 10 +lstringa<8> str; str.format("test = {} times", k);_cv 2.60 % 2.60 % 10 +lstringa<32> str; str.format("test = {} times", k);_mean 5041 ns 5041 ns 10 +lstringa<32> str; str.format("test = {} times", k);_median 4992 ns 4992 ns 10 +lstringa<32> str; str.format("test = {} times", k);_stddev 144 ns 144 ns 10 +lstringa<32> str; str.format("test = {} times", k);_cv 2.86 % 2.86 % 10 +lstringa<8> str = "test = " + k + " times";_mean 1865 ns 1865 ns 10 +lstringa<8> str = "test = " + k + " times";_median 1834 ns 1834 ns 10 +lstringa<8> str = "test = " + k + " times";_stddev 81.0 ns 81.1 ns 10 +lstringa<8> str = "test = " + k + " times";_cv 4.35 % 4.35 % 10 +lstringa<32> str = "test = " + k + " times";_mean 1202 ns 1202 ns 10 +lstringa<32> str = "test = " + k + " times";_median 1208 ns 1208 ns 10 +lstringa<32> str = "test = " + k + " times";_stddev 33.4 ns 33.4 ns 10 +lstringa<32> str = "test = " + k + " times";_cv 2.78 % 2.78 % 10 +stringa str = "test = " + k + " times";_mean 1715 ns 1715 ns 10 +stringa str = "test = " + k + " times";_median 1691 ns 1691 ns 10 +stringa str = "test = " + k + " times";_stddev 87.3 ns 87.3 ns 10 +stringa str = "test = " + k + " times";_cv 5.09 % 5.09 % 10 +-- Split text and convert to int --/repeats:1 0.000 ns 0.000 ns 1000000000 +std::string::find + substr + std::strtol_mean 1618 ns 1618 ns 10 +std::string::find + substr + std::strtol_median 1612 ns 1612 ns 10 +std::string::find + substr + std::strtol_stddev 62.7 ns 62.7 ns 10 +std::string::find + substr + std::strtol_cv 3.87 % 3.87 % 10 +ssa::splitter + ssa::as_int_mean 655 ns 655 ns 10 +ssa::splitter + ssa::as_int_median 657 ns 657 ns 10 +ssa::splitter + ssa::as_int_stddev 18.0 ns 18.0 ns 10 +ssa::splitter + ssa::as_int_cv 2.75 % 2.75 % 10 +ssa::splitf + functor_mean 899 ns 899 ns 10 +ssa::splitf + functor_median 894 ns 894 ns 10 +ssa::splitf + functor_stddev 33.7 ns 33.7 ns 10 +ssa::splitf + functor_cv 3.75 % 3.75 % 10 +-- Replace symbols in text ~400 symbols --/repeats:1 0.000 ns 0.000 ns 1000000000 +Naive (and wrong) replace symbols with std::string find + replace_mean 6193 ns 6193 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_median 6168 ns 6168 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_stddev 264 ns 264 ns 10 +Naive (and wrong) replace symbols with std::string find + replace_cv 4.26 % 4.26 % 10 +replace symbols with std::string find_first_of + replace_mean 9978 ns 9978 ns 10 +replace symbols with std::string find_first_of + replace_median 9940 ns 9940 ns 10 +replace symbols with std::string find_first_of + replace_stddev 147 ns 147 ns 10 +replace symbols with std::string find_first_of + replace_cv 1.48 % 1.48 % 10 +replace symbols with std::string_view find_first_of + copy_mean 10198 ns 10198 ns 10 +replace symbols with std::string_view find_first_of + copy_median 10229 ns 10229 ns 10 +replace symbols with std::string_view find_first_of + copy_stddev 361 ns 361 ns 10 +replace symbols with std::string_view find_first_of + copy_cv 3.54 % 3.54 % 10 +replace runtime symbols with string expressions and without remembering all search results_mean 5706 ns 5706 ns 10 +replace runtime symbols with string expressions and without remembering all search results_median 5705 ns 5705 ns 10 +replace runtime symbols with string expressions and without remembering all search results_stddev 208 ns 208 ns 10 +replace runtime symbols with string expressions and without remembering all search results_cv 3.65 % 3.65 % 10 +replace runtime symbols with simstr and memorization of all search results_mean 5029 ns 5029 ns 10 +replace runtime symbols with simstr and memorization of all search results_median 5010 ns 5010 ns 10 +replace runtime symbols with simstr and memorization of all search results_stddev 172 ns 172 ns 10 +replace runtime symbols with simstr and memorization of all search results_cv 3.41 % 3.41 % 10 +replace const symbols with string expressions and without remembering all search results_mean 4946 ns 4946 ns 10 +replace const symbols with string expressions and without remembering all search results_median 4876 ns 4876 ns 10 +replace const symbols with string expressions and without remembering all search results_stddev 239 ns 239 ns 10 +replace const symbols with string expressions and without remembering all search results_cv 4.84 % 4.84 % 10 +replace const symbols with string expressions and memorization of all search results_mean 4198 ns 4198 ns 10 +replace const symbols with string expressions and memorization of all search results_median 4225 ns 4225 ns 10 +replace const symbols with string expressions and memorization of all search results_stddev 117 ns 117 ns 10 +replace const symbols with string expressions and memorization of all search results_cv 2.78 % 2.78 % 10 +-- Replace symbols in text ~40 symbols --/repeats:1 0.000 ns 0.000 ns 1000000000 +Short Naive (and wrong) replace symbols with std::string find + replace_mean 1016 ns 1016 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_median 1026 ns 1026 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_stddev 47.9 ns 47.9 ns 10 +Short Naive (and wrong) replace symbols with std::string find + replace_cv 4.71 % 4.71 % 10 +Short replace symbols with std::string find_first_of + replace_mean 1431 ns 1431 ns 10 +Short replace symbols with std::string find_first_of + replace_median 1441 ns 1441 ns 10 +Short replace symbols with std::string find_first_of + replace_stddev 65.0 ns 65.0 ns 10 +Short replace symbols with std::string find_first_of + replace_cv 4.54 % 4.54 % 10 +Short replace symbols with std::string_view find_first_of + copy_mean 1417 ns 1417 ns 10 +Short replace symbols with std::string_view find_first_of + copy_median 1410 ns 1410 ns 10 +Short replace symbols with std::string_view find_first_of + copy_stddev 50.9 ns 50.9 ns 10 +Short replace symbols with std::string_view find_first_of + copy_cv 3.59 % 3.59 % 10 +Short replace runtime symbols with string expressions and without remembering all search results_mean 795 ns 795 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_median 800 ns 800 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_stddev 30.4 ns 30.5 ns 10 +Short replace runtime symbols with string expressions and without remembering all search results_cv 3.83 % 3.83 % 10 +Short replace runtime symbols with simstr and memorization of all search results_mean 847 ns 847 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_median 844 ns 844 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_stddev 15.6 ns 15.6 ns 10 +Short replace runtime symbols with simstr and memorization of all search results_cv 1.84 % 1.84 % 10 +Short replace const symbols with string expressions and without remembering all search results_mean 626 ns 626 ns 10 +Short replace const symbols with string expressions and without remembering all search results_median 624 ns 624 ns 10 +Short replace const symbols with string expressions and without remembering all search results_stddev 22.5 ns 22.5 ns 10 +Short replace const symbols with string expressions and without remembering all search results_cv 3.60 % 3.60 % 10 +Short replace const symbols with string expressions and memorization of all search results_mean 706 ns 706 ns 10 +Short replace const symbols with string expressions and memorization of all search results_median 696 ns 696 ns 10 +Short replace const symbols with string expressions and memorization of all search results_stddev 33.5 ns 33.5 ns 10 +Short replace const symbols with string expressions and memorization of all search results_cv 4.75 % 4.75 % 10 +----- Replace All Str To Longer Size ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +replace bb to ---- in std::string|64_mean 832 ns 832 ns 10 +replace bb to ---- in std::string|64_median 840 ns 840 ns 10 +replace bb to ---- in std::string|64_stddev 48.0 ns 48.0 ns 10 +replace bb to ---- in std::string|64_cv 5.77 % 5.77 % 10 +replace bb to ---- in std::string|256_mean 2559 ns 2559 ns 10 +replace bb to ---- in std::string|256_median 2526 ns 2526 ns 10 +replace bb to ---- in std::string|256_stddev 150 ns 150 ns 10 +replace bb to ---- in std::string|256_cv 5.88 % 5.88 % 10 +replace bb to ---- in std::string|512_mean 4466 ns 4466 ns 10 +replace bb to ---- in std::string|512_median 4489 ns 4489 ns 10 +replace bb to ---- in std::string|512_stddev 88.8 ns 88.8 ns 10 +replace bb to ---- in std::string|512_cv 1.99 % 1.99 % 10 +replace bb to ---- in std::string|1024_mean 8916 ns 8916 ns 10 +replace bb to ---- in std::string|1024_median 8819 ns 8819 ns 10 +replace bb to ---- in std::string|1024_stddev 415 ns 415 ns 10 +replace bb to ---- in std::string|1024_cv 4.65 % 4.65 % 10 +replace bb to ---- in std::string|2048_mean 19324 ns 19324 ns 10 +replace bb to ---- in std::string|2048_median 19249 ns 19249 ns 10 +replace bb to ---- in std::string|2048_stddev 511 ns 511 ns 10 +replace bb to ---- in std::string|2048_cv 2.65 % 2.65 % 10 +replace bb to ---- in lstringa<8>|64_mean 749 ns 749 ns 10 +replace bb to ---- in lstringa<8>|64_median 752 ns 752 ns 10 +replace bb to ---- in lstringa<8>|64_stddev 17.0 ns 17.0 ns 10 +replace bb to ---- in lstringa<8>|64_cv 2.28 % 2.28 % 10 +replace bb to ---- in lstringa<8>|256_mean 2053 ns 2053 ns 10 +replace bb to ---- in lstringa<8>|256_median 2088 ns 2088 ns 10 +replace bb to ---- in lstringa<8>|256_stddev 98.5 ns 98.5 ns 10 +replace bb to ---- in lstringa<8>|256_cv 4.80 % 4.80 % 10 +replace bb to ---- in lstringa<8>|512_mean 3754 ns 3754 ns 10 +replace bb to ---- in lstringa<8>|512_median 3695 ns 3695 ns 10 +replace bb to ---- in lstringa<8>|512_stddev 162 ns 162 ns 10 +replace bb to ---- in lstringa<8>|512_cv 4.32 % 4.32 % 10 +replace bb to ---- in lstringa<8>|1024_mean 6775 ns 6775 ns 10 +replace bb to ---- in lstringa<8>|1024_median 6776 ns 6776 ns 10 +replace bb to ---- in lstringa<8>|1024_stddev 196 ns 196 ns 10 +replace bb to ---- in lstringa<8>|1024_cv 2.89 % 2.89 % 10 +replace bb to ---- in lstringa<8>|2048_mean 13478 ns 13478 ns 10 +replace bb to ---- in lstringa<8>|2048_median 13420 ns 13421 ns 10 +replace bb to ---- in lstringa<8>|2048_stddev 436 ns 436 ns 10 +replace bb to ---- in lstringa<8>|2048_cv 3.24 % 3.24 % 10 +replace bb to ---- by init stringa|64_mean 503 ns 503 ns 10 +replace bb to ---- by init stringa|64_median 504 ns 504 ns 10 +replace bb to ---- by init stringa|64_stddev 19.5 ns 19.5 ns 10 +replace bb to ---- by init stringa|64_cv 3.86 % 3.86 % 10 +replace bb to ---- by init stringa|256_mean 1848 ns 1848 ns 10 +replace bb to ---- by init stringa|256_median 1828 ns 1828 ns 10 +replace bb to ---- by init stringa|256_stddev 80.6 ns 80.6 ns 10 +replace bb to ---- by init stringa|256_cv 4.36 % 4.36 % 10 +replace bb to ---- by init stringa|512_mean 3537 ns 3537 ns 10 +replace bb to ---- by init stringa|512_median 3552 ns 3552 ns 10 +replace bb to ---- by init stringa|512_stddev 85.6 ns 85.6 ns 10 +replace bb to ---- by init stringa|512_cv 2.42 % 2.42 % 10 +replace bb to ---- by init stringa|1024_mean 6923 ns 6923 ns 10 +replace bb to ---- by init stringa|1024_median 6991 ns 6991 ns 10 +replace bb to ---- by init stringa|1024_stddev 177 ns 177 ns 10 +replace bb to ---- by init stringa|1024_cv 2.55 % 2.55 % 10 +replace bb to ---- by init stringa|2048_mean 13739 ns 13739 ns 10 +replace bb to ---- by init stringa|2048_median 13659 ns 13660 ns 10 +replace bb to ---- by init stringa|2048_stddev 473 ns 473 ns 10 +replace bb to ---- by init stringa|2048_cv 3.44 % 3.44 % 10 +----- Replace All Str To Same Size ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +replace bb to -- in std::string|64_mean 570 ns 570 ns 10 +replace bb to -- in std::string|64_median 565 ns 565 ns 10 +replace bb to -- in std::string|64_stddev 20.7 ns 20.7 ns 10 +replace bb to -- in std::string|64_cv 3.63 % 3.63 % 10 +replace bb to -- in std::string|256_mean 1885 ns 1885 ns 10 +replace bb to -- in std::string|256_median 1910 ns 1910 ns 10 +replace bb to -- in std::string|256_stddev 84.9 ns 84.8 ns 10 +replace bb to -- in std::string|256_cv 4.50 % 4.50 % 10 +replace bb to -- in std::string|512_mean 3523 ns 3523 ns 10 +replace bb to -- in std::string|512_median 3551 ns 3551 ns 10 +replace bb to -- in std::string|512_stddev 110 ns 110 ns 10 +replace bb to -- in std::string|512_cv 3.13 % 3.13 % 10 +replace bb to -- in std::string|1024_mean 6916 ns 6916 ns 10 +replace bb to -- in std::string|1024_median 6933 ns 6933 ns 10 +replace bb to -- in std::string|1024_stddev 153 ns 153 ns 10 +replace bb to -- in std::string|1024_cv 2.21 % 2.21 % 10 +replace bb to -- in std::string|2048_mean 13510 ns 13510 ns 10 +replace bb to -- in std::string|2048_median 13336 ns 13336 ns 10 +replace bb to -- in std::string|2048_stddev 539 ns 539 ns 10 +replace bb to -- in std::string|2048_cv 3.99 % 3.99 % 10 +replace bb to -- in lstringa<8>|64_mean 482 ns 482 ns 10 +replace bb to -- in lstringa<8>|64_median 481 ns 481 ns 10 +replace bb to -- in lstringa<8>|64_stddev 9.24 ns 9.24 ns 10 +replace bb to -- in lstringa<8>|64_cv 1.92 % 1.92 % 10 +replace bb to -- in lstringa<8>|256_mean 1565 ns 1565 ns 10 +replace bb to -- in lstringa<8>|256_median 1571 ns 1571 ns 10 +replace bb to -- in lstringa<8>|256_stddev 44.1 ns 44.1 ns 10 +replace bb to -- in lstringa<8>|256_cv 2.82 % 2.82 % 10 +replace bb to -- in lstringa<8>|512_mean 2921 ns 2921 ns 10 +replace bb to -- in lstringa<8>|512_median 2922 ns 2922 ns 10 +replace bb to -- in lstringa<8>|512_stddev 85.4 ns 85.4 ns 10 +replace bb to -- in lstringa<8>|512_cv 2.92 % 2.92 % 10 +replace bb to -- in lstringa<8>|1024_mean 5594 ns 5594 ns 10 +replace bb to -- in lstringa<8>|1024_median 5521 ns 5521 ns 10 +replace bb to -- in lstringa<8>|1024_stddev 211 ns 211 ns 10 +replace bb to -- in lstringa<8>|1024_cv 3.78 % 3.78 % 10 +replace bb to -- in lstringa<8>|2048_mean 10928 ns 10928 ns 10 +replace bb to -- in lstringa<8>|2048_median 10821 ns 10821 ns 10 +replace bb to -- in lstringa<8>|2048_stddev 362 ns 362 ns 10 +replace bb to -- in lstringa<8>|2048_cv 3.32 % 3.32 % 10 +replace bb to -- by init stringa|64_mean 366 ns 366 ns 10 +replace bb to -- by init stringa|64_median 366 ns 366 ns 10 +replace bb to -- by init stringa|64_stddev 7.95 ns 7.95 ns 10 +replace bb to -- by init stringa|64_cv 2.17 % 2.17 % 10 +replace bb to -- by init stringa|256_mean 1224 ns 1224 ns 10 +replace bb to -- by init stringa|256_median 1222 ns 1222 ns 10 +replace bb to -- by init stringa|256_stddev 47.7 ns 47.7 ns 10 +replace bb to -- by init stringa|256_cv 3.90 % 3.90 % 10 +replace bb to -- by init stringa|512_mean 2221 ns 2221 ns 10 +replace bb to -- by init stringa|512_median 2224 ns 2224 ns 10 +replace bb to -- by init stringa|512_stddev 51.5 ns 51.5 ns 10 +replace bb to -- by init stringa|512_cv 2.32 % 2.32 % 10 +replace bb to -- by init stringa|1024_mean 4235 ns 4235 ns 10 +replace bb to -- by init stringa|1024_median 4272 ns 4272 ns 10 +replace bb to -- by init stringa|1024_stddev 139 ns 139 ns 10 +replace bb to -- by init stringa|1024_cv 3.29 % 3.29 % 10 +replace bb to -- by init stringa|2048_mean 8496 ns 8496 ns 10 +replace bb to -- by init stringa|2048_median 8383 ns 8383 ns 10 +replace bb to -- by init stringa|2048_stddev 251 ns 251 ns 10 +replace bb to -- by init stringa|2048_cv 2.95 % 2.95 % 10 +----- Hash Map insert and find ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +hashStrMapA emplace & find stringa;_mean 5327536 ns 5327558 ns 10 +hashStrMapA emplace & find stringa;_median 5331817 ns 5331835 ns 10 +hashStrMapA emplace & find stringa;_stddev 108137 ns 108137 ns 10 +hashStrMapA emplace & find stringa;_cv 2.03 % 2.03 % 10 +std::unordered_map emplace & find std::string;_mean 6172235 ns 6172321 ns 10 +std::unordered_map emplace & find std::string;_median 6158878 ns 6158954 ns 10 +std::unordered_map emplace & find std::string;_stddev 213624 ns 213652 ns 10 +std::unordered_map emplace & find std::string;_cv 3.46 % 3.46 % 10 +hashStrMapA emplace & find ssa;_mean 5318092 ns 5318133 ns 10 +hashStrMapA emplace & find ssa;_median 5302064 ns 5302156 ns 10 +hashStrMapA emplace & find ssa;_stddev 102639 ns 102632 ns 10 +hashStrMapA emplace & find ssa;_cv 1.93 % 1.93 % 10 +std::unordered_map emplace & find std::string_view;_mean 7002408 ns 7002477 ns 10 +std::unordered_map emplace & find std::string_view;_median 6998707 ns 6998736 ns 10 +std::unordered_map emplace & find std::string_view;_stddev 160708 ns 160734 ns 10 +std::unordered_map emplace & find std::string_view;_cv 2.30 % 2.30 % 10 +----- Build Full Func Name ---------/repeats:1 0.000 ns 0.000 ns 1000000000 +Build func full name std::string;_mean 5576 ns 5576 ns 10 +Build func full name std::string;_median 5532 ns 5532 ns 10 +Build func full name std::string;_stddev 298 ns 298 ns 10 +Build func full name std::string;_cv 5.35 % 5.35 % 10 +Build func full name std::string 1;_mean 5877 ns 5877 ns 10 +Build func full name std::string 1;_median 5896 ns 5896 ns 10 +Build func full name std::string 1;_stddev 247 ns 247 ns 10 +Build func full name std::string 1;_cv 4.20 % 4.20 % 10 +Build func full name std::stream;_mean 16604 ns 16604 ns 10 +Build func full name std::stream;_median 16552 ns 16552 ns 10 +Build func full name std::stream;_stddev 530 ns 530 ns 10 +Build func full name std::stream;_cv 3.19 % 3.19 % 10 +Build func full name stringa;_mean 2780 ns 2780 ns 10 +Build func full name stringa;_median 2749 ns 2749 ns 10 +Build func full name stringa;_stddev 87.2 ns 87.2 ns 10 +Build func full name stringa;_cv 3.13 % 3.14 % 10 +Build func full name stringa 1;_mean 3249 ns 3249 ns 10 +Build func full name stringa 1;_median 3205 ns 3205 ns 10 +Build func full name stringa 1;_stddev 137 ns 137 ns 10 +Build func full name stringa 1;_cv 4.22 % 4.22 % 10 diff --git a/docs/Doxyfile b/docs/Doxyfile new file mode 100644 index 0000000..23ae796 --- /dev/null +++ b/docs/Doxyfile @@ -0,0 +1,2970 @@ +# Doxyfile 1.13.2 + +# This file describes the settings to be used by the documentation system +# Doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use Doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use Doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "simstr" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = 1.0 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewers a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Yet another strings library" + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# With the PROJECT_ICON tag one can specify an icon that is included in the tabs +# when the HTML document is shown. Doxygen will copy the logo to the output +# directory. + +PROJECT_ICON = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where Doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = ../_build/docs + +# If the CREATE_SUBDIRS tag is set to YES then Doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this +# option can be useful when feeding Doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise cause +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + +# If the ALLOW_UNICODE_NAMES tag is set to YES, Doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by Doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = Russian + +# If the BRIEF_MEMBER_DESC tag is set to YES, Doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, Doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, Doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = YES + +# If the FULL_PATH_NAMES tag is set to YES, Doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = NO + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which Doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where Doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, Doxygen will generate much shorter (but +# less readable) file names. This can be useful if your file system doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen will interpret the +# first line (until the first dot, question mark or exclamation mark) of a +# Javadoc-style comment as the brief description. If set to NO, the Javadoc- +# style will behave just like regular Qt-style comments (thus requiring an +# explicit @brief command for a brief description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the JAVADOC_BANNER tag is set to YES then Doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by Doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will interpret the first +# line (until the first dot, question mark or exclamation mark) of a Qt-style +# comment as the brief description. If set to NO, the Qt-style will behave just +# like regular Qt-style comments (thus requiring an explicit \brief command for +# a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# By default Python docstrings are displayed as preformatted text and Doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# Doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as Doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then Doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:^^" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by Doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make Doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by Doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then Doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by Doxygen, so you can +# mix Doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 6. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 6 + +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0 and GITHUB use the lower case version of title +# with any whitespace replaced by '-' and punctuation characters removed. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + +# When enabled Doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. Words listed in the +# AUTOLINK_IGNORE_WORDS tag are excluded from automatic linking. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# This tag specifies a list of words that, when matching the start of a word in +# the documentation, will suppress auto links generation, if it is enabled via +# AUTOLINK_SUPPORT. This list does not affect affect links explicitly created +# using \# or the \link or commands. +# This tag requires that the tag AUTOLINK_SUPPORT is set to YES. + +AUTOLINK_IGNORE_WORDS = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let Doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also makes the inheritance and +# collaboration diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software) sources only. Doxygen will parse +# them like normal C++ but will assume all classes use public instead of private +# inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# Doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then Doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, Doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# Doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run Doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +# The NUM_PROC_THREADS specifies the number of threads Doxygen is allowed to use +# during processing. When set to 0 Doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = NO + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, Doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_UNDOC_NAMESPACES tag is set to YES, Doxygen will hide all +# undocumented namespaces that are normally visible in the namespace hierarchy. +# If set to NO, these namespaces will be included in the various overviews. This +# option has no effect if EXTRACT_ALL is enabled. +# The default value is: YES. + +HIDE_UNDOC_NAMESPACES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# With the correct setting of option CASE_SENSE_NAMES Doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and macOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. + +CASE_SENSE_NAMES = SYSTEM + +# If the HIDE_SCOPE_NAMES tag is set to NO then Doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then Doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then Doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then Doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then Doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then Doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then Doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and Doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING Doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# Doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by Doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by Doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents Doxygen's defaults, run Doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. +# +# Note that if you run Doxygen from a directory containing a file called +# DoxygenLayout.xml, Doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +# The EXTERNAL_TOOL_PATH tag can be used to extend the search path (PATH +# environment variable) so that external tools such as latex and gs can be +# found. +# Note: Directories specified with EXTERNAL_TOOL_PATH are added in front of the +# path already specified by the PATH variable, and are added in the order +# specified. +# Note: This option is particularly useful for macOS version 14 (Sonoma) and +# higher, when running Doxygen from Doxywizard, because in this case any user- +# defined changes to the PATH are ignored. A typical example on macOS is to set +# EXTERNAL_TOOL_PATH = /Library/TeX/texbin /usr/local/bin +# together with the standard path, the full search path used by doxygen when +# launching external tools will then become +# PATH=/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin + +EXTERNAL_TOOL_PATH = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by Doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by Doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then Doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, Doxygen will generate warnings for +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# If WARN_IF_INCOMPLETE_DOC is set to YES, Doxygen will warn about incomplete +# function parameter documentation. If set to NO, Doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, Doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, Doxygen will warn about +# undocumented enumeration values. If set to NO, Doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + +# If WARN_LAYOUT_FILE option is set to YES, Doxygen will warn about issues found +# while parsing the user defined layout file, such as missing or wrong elements. +# See also LAYOUT_FILE for details. If set to NO, problems with the layout file +# will be suppressed. +# The default value is: YES. + +WARN_LAYOUT_FILE = YES + +# If the WARN_AS_ERROR tag is set to YES then Doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then Doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the Doxygen process Doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then Doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined Doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that Doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of Doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = ../src ../include + +# This tag can be used to specify the character encoding of the source files +# that Doxygen parses. Internally Doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# This tag can be used to specify the character encoding of the source files +# that Doxygen parses. The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). +# See also: INPUT_ENCODING for further information on supported encodings. + +INPUT_FILE_ENCODING = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by Doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm, +# *.cpp, *.cppm, *.ccm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, +# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.ixx, *.l, *.cs, *.d, +# *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to +# be provided as Doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cxxm \ + *.cpp \ + *.cppm \ + *.ccm \ + *.c++ \ + *.c++m \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.ixx \ + *.l \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f18 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which Doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# ANamespace::AClass, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that Doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that Doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by Doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by Doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the Doxygen output. + +USE_MDFILE_AS_MAINPAGE = ../readme.md + +# If the IMPLICIT_DIR_DOCS tag is set to YES, any README.md file found in sub- +# directories of the project's root, is used as the documentation for that sub- +# directory, except when the README.md starts with a \dir, \page or \mainpage +# command. If set to NO, the README.md file needs to start with an explicit \dir +# command in order to be used as directory documentation. +# The default value is: YES. + +IMPLICIT_DIR_DOCS = YES + +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# multi-line macros, enums or list initialized variables directly into the +# documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct Doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of Doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by Doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then Doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then Doxygen will use the +# clang parser (see: +# http://clang.llvm.org/) for more accurate parsing at the cost of reduced +# performance. This can be particularly helpful with template rich C++ code for +# which Doxygen's built-in parser lacks the necessary type information. +# Note: The availability of this option depends on whether or not Doxygen was +# generated with the -Duse_libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS +# tag is set to YES then Doxygen will add the directory of each input to the +# include path. +# The default value is: YES. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_ADD_INC_PATHS = YES + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by Doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +# If clang assisted parsing is enabled you can provide the clang parser with the +# path to the directory containing a file called compile_commands.json. This +# file is the compilation database (see: +# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the +# options used when the source files were built. This is equivalent to +# specifying the -p option to a clang tool, such as clang-check. These options +# will then be passed to the parser. Any options specified with CLANG_OPTIONS +# will be added as well. +# Note: The availability of this option depends on whether or not Doxygen was +# generated with the -Duse_libclang=ON option for CMake. + +CLANG_DATABASE_PATH = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, Doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank Doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that Doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that Doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of Doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank Doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that Doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank Doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that Doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by Doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generates light mode output, DARK always +# generates dark mode output, AUTO_LIGHT automatically sets the mode according +# to the user preference, uses light mode if no preference is set (the default), +# AUTO_DARK automatically sets the mode according to the user preference, uses +# dark mode if no preference is set and TOGGLE allows a user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use gray-scales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be +# dynamically folded and expanded in the generated HTML source code. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_CODE_FOLDING = YES + +# If the HTML_COPY_CLIPBOARD tag is set to YES then Doxygen will show an icon in +# the top right corner of code and text fragments that allows the user to copy +# its content to the clipboard. Note this only works if supported by the browser +# and the web page is served via a secure context (see: +# https://www.w3.org/TR/secure-contexts/), i.e. using the https: or file: +# protocol. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COPY_CLIPBOARD = YES + +# Doxygen stores a couple of settings persistently in the browser (via e.g. +# cookies). By default these settings apply to all HTML pages generated by +# Doxygen across all projects. The HTML_PROJECT_COOKIE tag can be used to store +# the settings under a project specific key, such that the user preferences will +# be stored separately. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_PROJECT_COOKIE = + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, Doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then Doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline (the HTML help workshop was already many +# years in maintenance mode). You can download the HTML help workshop from the +# web archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by Doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# Doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty Doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = YES + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by Doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# Doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# When the SHOW_ENUM_VALUES tag is set doxygen will show the specified +# enumeration values besides the enumeration mnemonics. +# The default value is: NO. + +SHOW_ENUM_VALUES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, Doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# If the OBFUSCATE_EMAILS tag is set to YES, Doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, Doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# Doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for MathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with JavaScript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled Doxygen will generate a search box for +# the HTML output. The underlying search engine uses JavaScript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the JavaScript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /