commit 0cc4fad6e6d00f13a7325d9c125f4900add09820 Author: orefkov Date: Sat Apr 5 17:21:11 2025 +0300 First commit 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 +# , /