First commit

This commit is contained in:
orefkov 2025-04-05 17:21:11 +03:00 committed by Aleksandr Orefkov
commit 0cc4fad6e6
38 changed files with 29468 additions and 0 deletions

1481
.clang-format Normal file

File diff suppressed because it is too large Load Diff

175
.clang-tidy Normal file
View File

@ -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'

3
.clangd Normal file
View File

@ -0,0 +1,3 @@
CompileFlags:
Add: [-D_CLANGD=1, /std:c++20]
CompilationDatabase: _build/

9
.editorconfig Normal file
View File

@ -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

28
.gitattributes vendored Normal file
View File

@ -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

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
_build/
build/
out/
!.gitignore
*.ipch
*.VC.*
.vs/
.vscode/
CMakeUserPresets.json

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "ThirdParty/simdutf"]
path = ThirdParty/simdutf
url = https://github.com/simdutf/simdutf.git

90
CMakeLists.txt Normal file
View File

@ -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 ()

191
CMakePresets.json Normal file
View File

@ -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": [
]
}

21
LICENSE Normal file
View File

@ -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.

1
ThirdParty/simdutf vendored Submodule

@ -0,0 +1 @@
Subproject commit dd192d6fc5fdf0ad21c0759cd3133bbcc7ae4122

16
bench/CMakeLists.txt Normal file
View File

@ -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)

12
bench/bench.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include <simstr/sstring.h>
#include <benchmark/benchmark.h>
#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

1
bench/bench.js Normal file
View File

@ -0,0 +1 @@
Module.arguments=['--benchmark_repetitions=10', '--benchmark_report_aggregates_only=true'];

1906
bench/bench_str.cpp Normal file

File diff suppressed because it is too large Load Diff

351
bench/comments.txt Normal file
View File

@ -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<int, true, 10, false>
Здесь для to_int заданы такие же ограничения - проверять переполнение,
десятичная система, без лидирующих пробелов и знака плюс
- ssa s = "123456789"; int res = s.to_int<int, true, 10, false>
- lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>
- 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<int, true, 16, false>
- ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>
- lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>
- std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);
А здесь уже парсинг произвольного числа.
- stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow
- ssa s = " 123456789"; int res = s.to_int<int, false>; // 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<size_t> emplace & find stringa;
Вставляем в hashStrMapA 10000 stringa длиной от 30 до 50
символов, а потом ищем их в ней
- std::unordered_map<std::string, size_t> emplace & find std::string;
То же самое c std::string и std::unordered_map
- hashStrMapA<size_t> emplace & find ssa;
Теперь вставляем stringa, а ищем ssa
- std::unordered_map<std::string, size_t> 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 строках и строковых выражениях.
Инфа о параметрах добавляется во временную строку, а потом
разом добавляется в текущую строку. Позволяет операции в цикле
записать в одну строку, но чуть проигрывает по времени выполнения.
- Пусто

270
bench/header.txt Normal file
View File

@ -0,0 +1,270 @@
<html>
<head>
<meta charset="UTF-8" />
<link href="results.css" rel="stylesheet" />
<title>SimStr benchmarks results</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
let bench_sets = {};
let activeBuilder = buildTestsByPlatformsBar;
let buildAsLine = {
"Copy not literal Str with N symbols": "Length of the copied string",
"Replace All Str To Longer Size": "Length of the string to be replaced",
"Replace All Str To Same Size": "Length of the string to be replaced"
};
function hl() {
document.querySelectorAll('.tooltiptext.code').forEach((el) => {
hljs.highlightElement(el);
});
}
function addBarChart(id, data) {
let canvas = document.getElementById('chart' + id);
new Chart(canvas, {
type: 'bar',
data: data,
options: {
scales: {
y: {
beginAtZero: true
},
x: {
title: {
text: "Time (ns)",
display: true
}
}
},
indexAxis: 'y',
plugins: {
legend: {
position: 'right',
labels: {
font: {
family: "'Cascadia Code', Consolas, 'Courier New', Courier, monospace"
}
}
}
}
}
});
}
function platformChecked(idx) {
return document.getElementById('pl' + idx).checked;
}
function buildPlatformsByTestsBar(bsName) {
if (buildAsLine[bsName]) {
buildPlatformsByTestsLine(bsName, buildAsLine[bsName]);
return;
}
let data = { labels: [], datasets: [] };
for (const i in platform_names) {
if (platformChecked(i))
data.datasets.push({ label: platform_names[i], data: [], borderWidth: 1 });
}
let bs = bench_sets[bsName];
for (const test of bs.tests) {
data.labels.push(test.name);
let ds = 0;
for (const i in test.data) {
if (platformChecked(i)) {
data.datasets[ds++].data.push(test.data[i]);
}
}
}
addBarChart(bs.id, data);
}
function buildTestsByPlatformsBar(bsName) {
if (buildAsLine[bsName], buildAsLine[bsName]) {
buildTestsByPlatformsLine(bsName, buildAsLine[bsName]);
return;
}
let data = { labels: [], datasets: [] };
let bs = bench_sets[bsName];
for (const test of bs.tests) {
data.datasets.push({ label: test.name, data: [], borderWidth: 1 });
}
for (const i in platform_names) {
if (platformChecked(i)) {
data.labels.push(platform_names[i]);
for (const j in bs.tests) {
data.datasets[j].data.push(bs.tests[j].data[i]);
}
}
}
addBarChart(bs.id, data);
}
function buildCanvas(plCount) {
document.querySelectorAll("canvas.bench_chart").forEach(e => e.remove());
for (var bs_name in bench_sets) {
let bs = bench_sets[bs_name];
if (plCount) {
let canvas = document.createElement('canvas');
canvas.id = "chart" + bs.id;
canvas.classList.add('bench_chart');
let h = 20 * plCount * bs.tests.length;
canvas.style.width = "100%";
canvas.style.height = h + "px";
canvas.height = h * devicePixelRatio;
document.getElementById(bs.id).after(canvas);
}
}
}
function addLineChart(canvas, data, title, scaleTitle) {
new Chart(canvas, {
type: 'line',
data: data,
options: {
scales: {
y: {
beginAtZero: true,
title: {
text: scaleTitle,
display: true
}
},
x: {
title: {
text: "Time (ns)",
display: true
}
}
},
indexAxis: 'y',
plugins: {
title: {
display: true,
text: title,
},
legend: {
position: 'right',
labels: {
font: {
family: "'Cascadia Code', Consolas, 'Courier New', Courier, monospace"
}
}
}
}
}
});
}
function buildTestsByPlatformsLineOne(bs, canvas, plIdx, scaleTitle) {
let data = { datasets: [] };
let prevTest = '';
let curData = undefined;
for (const test of bs.tests) {
let m = test.name.match(/(.+)[\/\|](\d+)$/);
if (m[1] != prevTest) {
prevTest = m[1];
curData = { label: prevTest, data: [], borderWidth: 1 };
data.datasets.push(curData);
}
curData.data.push([test.data[plIdx], m[2]]);
}
addLineChart(canvas, data, platform_names[plIdx], scaleTitle);
}
function buildTestsByPlatformsLine(bsName, scaleTitle) {
let bs = bench_sets[bsName];
let canvas = document.getElementById('chart' + bs.id);
let after = null;
for (const i in platform_names) {
if (platformChecked(i)) {
if (!canvas) {
canvas = document.createElement('canvas');
canvas.classList.add('bench_chart');
canvas.style.width = "100%";
after.after(canvas);
}
canvas.style.height = "300px";
canvas.height = 300 * devicePixelRatio;
buildTestsByPlatformsLineOne(bs, canvas, i, scaleTitle);
after = canvas;
canvas = null;
}
}
}
function buildPlatformsByTestsLineOne(bs, canvas, after, testData, title, scaleTitle) {
let data = { datasets: [] };
for (const i in platform_names) {
if (platformChecked(i)) {
ds = {label: platform_names[i], data: []};
for (const test of testData) {
ds.data.push([test.data[i], test.count]);
}
data.datasets.push(ds);
}
}
if (!canvas) {
canvas = document.createElement('canvas');
canvas.classList.add('bench_chart');
canvas.style.width = "100%";
after.after(canvas);
}
canvas.style.height = "300px";
canvas.height = 300 * devicePixelRatio;
addLineChart(canvas, data, title, scaleTitle);
return canvas;
}
function buildPlatformsByTestsLine(bsName, scaleTitle) {
let bs = bench_sets[bsName];
let canvas = document.getElementById('chart' + bs.id);
let after = null;
let data = [];
let prevTest = '';
for (const test of bs.tests) {
let m = test.name.match(/(.+)[\/\|](\d+)$/);
if (m[1] != prevTest) {
if (data.length) {
after = buildPlatformsByTestsLineOne(bs, canvas, after, data, prevTest, scaleTitle);
canvas = null;
}
prevTest = m[1];
data = [];
}
data.push({count: m[2], data: test.data});
}
if (data.length) {
buildPlatformsByTestsLineOne(bs, canvas, after, data, prevTest, scaleTitle);
}
}
function buildCharts() {
let plCount = 0;
for (const i in platform_names) {
if (platformChecked(i))
plCount++;
}
buildCanvas(plCount);
for (var bs_name in bench_sets) {
activeBuilder(bs_name);
}
}
function switchGrouping() {
activeBuilder = document.getElementById('gbp').checked ? buildTestsByPlatformsBar : buildPlatformsByTestsBar;
buildCharts();
}
document.addEventListener('DOMContentLoaded', (event) => {
if (!hljs) {
let scriptTag = document.createElement('script');
scriptTag.src = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js";
scriptTag.onload = hl;
scriptTag.onreadystatechange = hl;
document.body.appendChild(scriptTag);
} else {
hl();
}
if (!Chart) {
let scriptTag = document.createElement('script');
scriptTag.src = "https://cdn.jsdelivr.net/npm/chart.js";
scriptTag.onload = buildCharts;
scriptTag.onreadystatechange = buildCharts;
document.body.appendChild(scriptTag);
} else {
buildCharts();
}
});
</script>
</head><body><div class="header"><h2>SimStr benchmarks results</h2>
<span>All times in ns.</span>
<span><a href="https://github.com/orefkov/simstr/blob/main/bench/bench_str.cpp">Source for benchmarks</a></span>

356
bench/process_result.cpp Normal file
View File

@ -0,0 +1,356 @@
#include <simstr/sstring.h>
#include <filesystem>
#include <fstream>
#include <array>
#include <algorithm>
using namespace simstr;
struct result_info;
using out_t = lstringa<0>;
using results_vector = std::vector<result_info>;
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<typename T>
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<stringa> fileNames;
for (const auto& f: std::filesystem::directory_iterator{str_to_path(dirForResults)}) {
if (f.is_regular_file()) {
auto fileName = path_to_str<lstringa<64>>(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<unsigned, false, 10, false, false>()) == 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 = "<script>const platform_names=[";
out += R"=(<div>Group tests by platforms in charts: <input type="checkbox" id="gbp" checked onchange="switchGrouping()"/></div><div class="test_platforms"><h3>Test configurations:</h3><ul>)=";
unsigned counter = 0;
for (const auto& r : results) {
size_t rp = r.cpu_info_.find('(') + 1, lp = r.cpu_info_.find(')', rp);
ssa shortCpuInfo = r.cpu_info_.from_to(rp, lp);
ssa cpuInfo = r.cpu_info_(lp + 2);
out.append_formatted(R"--(
<li><span class="platform">{}</span><span class="tooltip">{}<span class="tooltiptext">{}</span></span>&nbsp;Include in charts: <input type="checkbox" id="pl{}" checked onchange="buildCharts()"/></li>)--",
r.platform_, shortCpuInfo, cpuInfo, counter++);
script += "'" + e_repl(r.platform_.to_str(), "'", "\\'") + "'" + e_choice(&r == &results.back(), "]", ",");
}
out += "\n</ul></div></div>\n" + script + ";</script>\n";
}
auto repl_html_symbols(ssa text) {
return e_repl_const_symbols(text, '\"', "&quot;", '<', "&lt;", '\'', "&#39;", '&', "&amp;");
}
void write_benchset_header(out_t& out, const results_vector& results, ssa benchsetName, unsigned id) {
size_t width = 40 / results.size();
out += "\n\n<div class=\"benchset\" id=\"bs"_ss + id + "\"><h4>" + repl_html_symbols(benchsetName) + "</h4>\n<table><thead><tr><th>Benchmark name</th><th width=\"5%\">Comment</th>";
for (const auto& r : results) {
out += "<th width=\""_ss + width + "%\">" + r.platform_ + "</th>";
}
out += "</tr></thead><tbody>";
}
void write_benchset_footer(out_t& out, ssa script) {
out += "\n</tbody></table></div><script>" + script + "}\n]}</script>";
}
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 += "<td class=\"benchmarkresult\">" + result + "</td>";
script_text += e_choice(result[0] == 'N', "NaN", result) + e_choice(last, "]", ",");
}
ssa extract_source_for_benchmark(ssa benchName, ssa sourceText) {
static hashStrMapA<stringa> textes;
size_t delim = benchName.find_last('/');
if (delim != str::npos && std::get<1>(benchName(delim + 1).to_int<unsigned, false, 10, false, false>()) == 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<u8s>{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<Splitter<u8s>> 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<tr><td class=\"benchmarkname\"><span class=\"tooltip\">" +
repl_html_symbols(benchName) +
"<span class=\"tooltiptext code\">" +
source + "</span></span></td><td>" +
e_if(!comment.is_empty(), "<span class=\"tooltip info\">&nbsp;>>&nbsp;<span class=\"tooltiptext\">" + comment + "</span></span>") +
"</td>";
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 += "</tr>";
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 += "</body></html>";
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;
}

105
bench/results.css Normal file
View File

@ -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;
}

3769
bench/results.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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<int, true, 10, false>_mean 13.7 ns 13.7 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_median 13.7 ns 13.7 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 0.303 ns 0.303 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_cv 2.21 % 2.21 % 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_mean 13.2 ns 13.2 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_median 13.2 ns 13.2 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 0.187 ns 0.187 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_cv 1.41 % 1.41 % 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_mean 12.8 ns 12.8 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_median 12.7 ns 12.7 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 0.256 ns 0.256 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_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<int, true, 16, false>_mean 11.8 ns 11.8 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 11.8 ns 11.8 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.179 ns 0.179 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_cv 1.52 % 1.52 % 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_mean 11.6 ns 11.6 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 11.6 ns 11.6 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.327 ns 0.327 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_cv 2.83 % 2.83 % 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_mean 11.5 ns 11.5 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 11.5 ns 11.5 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.224 ns 0.224 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_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<int>; // Check overflow_mean 22.1 ns 22.1 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_median 22.0 ns 22.0 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_stddev 0.224 ns 0.224 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_cv 1.01 % 1.01 % 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_mean 15.8 ns 15.8 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_median 15.8 ns 15.8 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_stddev 0.195 ns 0.195 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // 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<size_t> emplace & find stringa;_mean 3718900 ns 3718917 ns 10
hashStrMapA<size_t> emplace & find stringa;_median 3693440 ns 3693461 ns 10
hashStrMapA<size_t> emplace & find stringa;_stddev 53764 ns 53763 ns 10
hashStrMapA<size_t> emplace & find stringa;_cv 1.45 % 1.45 % 10
std::unordered_map<std::string, size_t> emplace & find std::string;_mean 3691442 ns 3691453 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_median 3673099 ns 3673111 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_stddev 139694 ns 139694 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_cv 3.78 % 3.78 % 10
hashStrMapA<size_t> emplace & find ssa;_mean 3719844 ns 3719860 ns 10
hashStrMapA<size_t> emplace & find ssa;_median 3711079 ns 3711094 ns 10
hashStrMapA<size_t> emplace & find ssa;_stddev 26128 ns 26129 ns 10
hashStrMapA<size_t> emplace & find ssa;_cv 0.70 % 0.70 % 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_mean 4115786 ns 4115803 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_median 4138618 ns 4138635 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_stddev 84101 ns 84103 ns 10
std::unordered_map<std::string, size_t> 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

View File

@ -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<int, true, 10, false>_mean 7.92 ns 7.92 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_median 7.90 ns 7.90 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 0.170 ns 0.170 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_cv 2.15 % 2.15 % 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_mean 7.73 ns 7.73 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_median 7.70 ns 7.70 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 0.126 ns 0.126 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_cv 1.63 % 1.63 % 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_mean 7.73 ns 7.73 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_median 7.60 ns 7.60 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 0.343 ns 0.343 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_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<int, true, 16, false>_mean 7.55 ns 7.55 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 7.48 ns 7.48 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.242 ns 0.242 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_cv 3.20 % 3.20 % 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_mean 8.28 ns 8.28 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 8.20 ns 8.20 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.205 ns 0.205 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_cv 2.48 % 2.48 % 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_mean 8.16 ns 8.16 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 8.11 ns 8.11 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.113 ns 0.113 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_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<int>; // Check overflow_mean 16.7 ns 16.7 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_median 16.8 ns 16.8 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_stddev 0.714 ns 0.714 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_cv 4.27 % 4.27 % 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_mean 14.6 ns 14.6 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_median 14.6 ns 14.6 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_stddev 0.378 ns 0.378 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // 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<size_t> emplace & find stringa;_mean 3769704 ns 3769718 ns 10
hashStrMapA<size_t> emplace & find stringa;_median 3760472 ns 3760485 ns 10
hashStrMapA<size_t> emplace & find stringa;_stddev 60750 ns 60751 ns 10
hashStrMapA<size_t> emplace & find stringa;_cv 1.61 % 1.61 % 10
std::unordered_map<std::string, size_t> emplace & find std::string;_mean 3652417 ns 3652436 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_median 3645060 ns 3645073 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_stddev 82821 ns 82811 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_cv 2.27 % 2.27 % 10
hashStrMapA<size_t> emplace & find ssa;_mean 3800957 ns 3800973 ns 10
hashStrMapA<size_t> emplace & find ssa;_median 3796589 ns 3796604 ns 10
hashStrMapA<size_t> emplace & find ssa;_stddev 47150 ns 47150 ns 10
hashStrMapA<size_t> emplace & find ssa;_cv 1.24 % 1.24 % 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_mean 4103196 ns 4103210 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_median 4108227 ns 4108241 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_stddev 68621 ns 68620 ns 10
std::unordered_map<std::string, size_t> 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

View File

@ -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<int, true, 10, false>_mean 13.3 ns 13.2 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_median 13.3 ns 13.3 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 0.207 ns 0.270 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_cv 1.55 % 2.04 % 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_mean 13.0 ns 13.0 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_median 13.1 ns 13.0 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 0.137 ns 0.237 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_cv 1.05 % 1.83 % 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_mean 13.2 ns 13.2 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_median 13.3 ns 13.2 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 0.184 ns 0.232 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_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<int, true, 16, false>_mean 11.4 ns 11.4 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 11.3 ns 11.4 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.296 ns 0.327 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_cv 2.59 % 2.86 % 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_mean 10.8 ns 10.7 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 10.7 ns 10.7 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.205 ns 0.230 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_cv 1.91 % 2.14 % 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_mean 11.2 ns 11.1 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 11.2 ns 11.0 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.125 ns 0.262 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_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<int>; // Check overflow_mean 18.8 ns 18.6 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_median 18.6 ns 18.6 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_stddev 0.412 ns 0.293 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_cv 2.20 % 1.57 % 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_mean 15.9 ns 15.8 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_median 15.9 ns 16.0 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_stddev 0.196 ns 0.294 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // 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<size_t> emplace & find stringa;_mean 4144900 ns 4132154 ns 10
hashStrMapA<size_t> emplace & find stringa;_median 4145547 ns 4094503 ns 10
hashStrMapA<size_t> emplace & find stringa;_stddev 160485 ns 168671 ns 10
hashStrMapA<size_t> emplace & find stringa;_cv 3.87 % 4.08 % 10
std::unordered_map<std::string, size_t> emplace & find std::string;_mean 5984962 ns 5929129 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_median 5980382 ns 5929129 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_stddev 115002 ns 118560 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_cv 1.92 % 2.00 % 10
hashStrMapA<size_t> emplace & find ssa;_mean 3983708 ns 3942587 ns 10
hashStrMapA<size_t> emplace & find ssa;_median 3962420 ns 3906250 ns 10
hashStrMapA<size_t> emplace & find ssa;_stddev 76626 ns 97653 ns 10
hashStrMapA<size_t> emplace & find ssa;_cv 1.92 % 2.48 % 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_mean 7030276 ns 7003348 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_median 6994535 ns 6975446 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_stddev 131572 ns 158383 ns 10
std::unordered_map<std::string, size_t> 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

View File

@ -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<int, true, 10, false>_mean 15.4 ns 15.3 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_median 15.4 ns 15.4 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 0.153 ns 0.258 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_cv 1.00 % 1.69 % 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_mean 15.1 ns 15.1 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_median 15.0 ns 15.1 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 0.250 ns 0.362 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_cv 1.66 % 2.41 % 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_mean 14.9 ns 14.8 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_median 15.0 ns 14.9 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 0.290 ns 0.333 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_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<int, true, 16, false>_mean 13.8 ns 13.6 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 13.6 ns 13.7 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.516 ns 0.244 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_cv 3.74 % 1.79 % 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_mean 12.8 ns 12.8 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 12.8 ns 12.8 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.202 ns 0.158 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_cv 1.58 % 1.24 % 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_mean 12.8 ns 12.6 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 12.8 ns 12.6 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.167 ns 0.265 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_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<int>; // Check overflow_mean 22.4 ns 22.2 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_median 22.3 ns 22.2 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_stddev 0.215 ns 0.366 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_cv 0.96 % 1.65 % 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_mean 19.0 ns 19.0 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_median 19.0 ns 18.8 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_stddev 0.223 ns 0.293 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // 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<size_t> emplace & find stringa;_mean 4237335 ns 4230925 ns 10
hashStrMapA<size_t> emplace & find stringa;_median 4253455 ns 4261364 ns 10
hashStrMapA<size_t> emplace & find stringa;_stddev 162581 ns 151627 ns 10
hashStrMapA<size_t> emplace & find stringa;_cv 3.84 % 3.58 % 10
std::unordered_map<std::string, size_t> emplace & find std::string;_mean 5468019 ns 5343750 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_median 5365539 ns 5312500 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_stddev 272590 ns 98821 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_cv 4.99 % 1.85 % 10
hashStrMapA<size_t> emplace & find ssa;_mean 3990921 ns 3919344 ns 10
hashStrMapA<size_t> emplace & find ssa;_median 3971040 ns 3928073 ns 10
hashStrMapA<size_t> emplace & find ssa;_stddev 113397 ns 145193 ns 10
hashStrMapA<size_t> emplace & find ssa;_cv 2.84 % 3.70 % 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_mean 6304651 ns 6305804 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_median 6263162 ns 6277902 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_stddev 161063 ns 171495 ns 10
std::unordered_map<std::string, size_t> 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

View File

@ -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<int, true, 10, false>_mean 55.2 ns 55.2 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_median 54.5 ns 54.5 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 1.79 ns 1.79 ns 10
stringa s = "123456789"; int res = s.to_int<int, true, 10, false>_cv 3.25 % 3.25 % 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_mean 51.0 ns 51.0 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_median 51.1 ns 51.1 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 1.67 ns 1.67 ns 10
ssa s = "123456789"; int res = s.to_int<int, true, 10, false>_cv 3.27 % 3.27 % 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_mean 52.1 ns 52.1 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_median 51.3 ns 51.3 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_stddev 1.94 ns 1.94 ns 10
lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>_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<int, true, 16, false>_mean 51.8 ns 51.8 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 51.5 ns 51.5 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.900 ns 0.900 ns 10
stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>_cv 1.74 % 1.74 % 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_mean 50.0 ns 50.0 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 50.1 ns 50.1 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 0.773 ns 0.773 ns 10
ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>_cv 1.55 % 1.55 % 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_mean 51.4 ns 51.4 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_median 50.8 ns 50.8 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_stddev 1.46 ns 1.46 ns 10
lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>_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<int>; // Check overflow_mean 74.8 ns 74.8 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_median 75.4 ns 75.4 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_stddev 2.69 ns 2.69 ns 10
stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow_cv 3.60 % 3.60 % 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_mean 51.3 ns 51.3 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_median 51.3 ns 51.3 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow_stddev 0.921 ns 0.921 ns 10
ssa s = " 123456789"; int res = s.to_int<int, false>; // 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<size_t> emplace & find stringa;_mean 5327536 ns 5327558 ns 10
hashStrMapA<size_t> emplace & find stringa;_median 5331817 ns 5331835 ns 10
hashStrMapA<size_t> emplace & find stringa;_stddev 108137 ns 108137 ns 10
hashStrMapA<size_t> emplace & find stringa;_cv 2.03 % 2.03 % 10
std::unordered_map<std::string, size_t> emplace & find std::string;_mean 6172235 ns 6172321 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_median 6158878 ns 6158954 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_stddev 213624 ns 213652 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string;_cv 3.46 % 3.46 % 10
hashStrMapA<size_t> emplace & find ssa;_mean 5318092 ns 5318133 ns 10
hashStrMapA<size_t> emplace & find ssa;_median 5302064 ns 5302156 ns 10
hashStrMapA<size_t> emplace & find ssa;_stddev 102639 ns 102632 ns 10
hashStrMapA<size_t> emplace & find ssa;_cv 1.93 % 1.93 % 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_mean 7002408 ns 7002477 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_median 6998707 ns 6998736 ns 10
std::unordered_map<std::string, size_t> emplace & find std::string_view;_stddev 160708 ns 160734 ns 10
std::unordered_map<std::string, size_t> 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

2970
docs/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

739
docs/overview.md Normal file
View File

@ -0,0 +1,739 @@
# Строки в С++
(, что с вами не так?)
<cite>
В ретроспективе 1991 года по истории C++ его создатель Бьярне Страуструп назвал отсутствие стандартного строкового типа
(и некоторых других стандартных типов) в C++ 1.0 худшей ошибкой, которую он допустил при его разработке:
"the absence of those led to everybody re-inventing the wheel and to an unnecessary diversity in the most fundamental classes"
(«Их отсутствие привело к тому, что все заново изобретали велосипед, и к ненужному разнообразию в самых фундаментальных классах»).
</cite>
## Что было и есть
Во вступительной части я хочу немного описать, каково ныне состояние со строками в С++, как мы к нему докатились и почему оно таково.
А также описать недостатки текущих реализаций, чтобы были понятны решения, которые я использую в своей библиотеке строк.
Собственно, изначально как такового стандартного типа для строк в С++ не было.
Для работы со строками использовался подход из C строка есть указатель на массив байтов, оканчивающихся нулём.
Недостатки таких строк — невозможно в строке использовать байт `0`, т. е. не подходит для бинарных данных,
непонятна стратегия управления/владения ресурсами, ну и основной недостаток — длину строки приходится вычислять каждый раз,
перебирая все её символы.
Откуда ноги растут у такого решения вполне понятно — со времён динозавров: как динозавры были большие, с маленьким мозгом и
короткими ручками, так и компьютеры были большие, память у них была маленькая, а строки короткими. Сэкономить память на хранении длины строки было важнее, чем потерять время на повторный подсчет длины.
Первые попытки стандартизировать строки как класс начались только в С++98 - std::string появился, как часть STL, и как
многое из STL, крайне неоднозначно воспринимался программистами.
И первое, что приходит в голову при улучшении C-строк — надо хранить длину строки:
```cpp
struct simple_string {
    const char* data;
    size_t length;
};
```
При наличии такой строки, уже множество алгоритмов значительно оптимизируются.
Например, при сравнении двух строк на равенство мы можем даже не начинать сравнивать их символы, если длины строк не равны.
Более того, этих данных абсолютно достаточно для всех методов, которые не модифицируют строку.
Также заметим, что такой объект на современных 64-битных архитектурах прекрасно передается в функции по значению —
оба его поля укладываются в регистры (ну, кроме windows), что облегчает работу оптимизатору компилятора.
Между тем, такое решение попало в стандарт только аж в С++17, в виде `std::string_view`.
Видимо, только тогда до комитета смогли донести мысль, что строки строкам рознь, и использовать только один универсальный объект
для строк — по меньшей мере может приводить к уменьшению производительности, а также нарушает принцип «не плати за то,
чем не пользуешься». Почему же «строки строкам рознь» и почему нам мало одного типа для строки, рассмотрим как раз далее.
И следующий вопрос, возникающий со строками — это владение ресурсами.
Практически каждый крупный фреймворк решал эту задачу самостоятельно, изобретая свои велосипеды.
У нас есть `std::string`, в QT у нас `QString`, в MFC - `CString`, в ATL - `CAtlString`, свои строки есть в Folly,
в общем, “тысячи их”, любой игровой движок начинают с того, чтобы написать свои строки.
Многие из этих реализаций в аспекте управления ресурсами для улучшения производительности использовали подход
**COW** “Copy On Write”. При этом объект строки ссылался на некий разделяемый между несколькими объектами буфер с символами
строки и счётчиком ссылок на этот буфер, что позволяло быстро создавать копию строки.
Но все они совпадали в одном — строка всегда предполагалась мутабельной, то есть что мы можем модифицировать символы в буфере строки.
Из-за этого подход **COW** умер к С++11: при каждой операции, могущей модифицировать символы строки приходилось проверять,
не ссылаемся ли мы на разделяемый буфер и если да, то копировать символы в другой буфер.
В многопоточной же среде потом ещё и проверять, не надо ли теперь освобождать старый буфер, и естественно всё это обмазавшись
локами или атомиками, что тоже не бесплатно.
Поэтому, начиная с С++11 `std::string` не использует **COW**, и каждое копирование объекта строки приводит и к копированию
всех символов строки в другой буфер.
Естественно, что каждый новый буфер требует аллокации памяти, что пытаются немного оптимизировать за счёт **SSO**
“Small String Optimization”, когда объект строки содержит внутри себя небольшой буфер и символы коротких строк
располагаются прямо в нём.
Но это уже зависит от реализации: в одних библиотеках помещают в объект строки до 15 байт, в некоторых до 23.
Однако эта оптимизация тоже палка о двух концах, и может в различных реализациях сделать строку "non trivial moveable".
А без COW мутабельность строк приводит к тому, что любая инициализация объекта строки приводит к копированию байтов.
Посмотрим такой код:
```cpp
const char* text1 = "Hello, World";         // ничего не стоит
std::string_view text2 = "Hello, World";    // Ничего не стоит, вычисляет длину строки при компиляции
std::string text3 = "Hello, World";         // В рантайме каждый раз копирует символы строки
```
(Удостоверится в правдивости комментариев можно на https://godbolt.org/z/51oKGWT5T )
Но если нам дальше по коду не нужно никак модифицировать строку, мы зря платим за аллокацию, копирование символов,
а также за деструктор строки. То есть хотелось бы иметь как минимум два варианта строк — мутабельные и иммутабельные,
чтобы явно дать понять компилятору, что мы не собираемся модифицировать строку.
Или банальный пример — мы парсим какой-то входящий буфер данных, нам нужно проверить, равен ли некий кусок буфера строке
”hello” на «чистом С++», т. е. без всяких memcmp и strcmp. До появления string_view приходилось делать примерно так:
```cpp
bool is_part_buffer_equal_hello(const char* data, int start, int end) {
    return std::string(data + start, end - start) == "hello";
}
```
Тут получается, сначала копируются символы из буфера data в буфер временной строки, возможно с аллокацией памяти, и лишь
потом временная строка сравнивается с ”hello”, а потом ещё и деструктор и раскрутка стека на случай исключения.
При использовании же вместо `std::string` `std::string_view` код на C++ почти не меняется:
```cpp
bool is_part_buffer_equal_hello_view(const char* data, int start, int end) {
    return std::string_view(data + start, end - start) == "hello";
}
```
Однако генерируемый машинный код значительно преобразуется, достигая уровня ручного С-кода — там просто сравнивается,
что end start == 5 и дальше кусок начального буфера сравнивается через memcmp со строкой ”hello”
(при -O2 c константами 1819043176 (hell) и 111 (o)).
Ни создания временного объекта, ни копирования байтов, ни деструктора, ни раскрутки стека для исключений.
Убедится можно на https://godbolt.org/z/9fo188e7c
Казалось бы, ну вот же в С++17 появился `string_view`, пожалуйста, используй его в параметрах своих функций вместо `const std::string&`,
и будет счастье. Но тут тоже есть нюанс — всё отлично работает, пока нам не нужно передать строку в стороннее C-API: string_view не даёт
гарантий нуль-терминированности строки, поэтому его data() нельзя передать в стороннее C-API, и потому всё-равно придётся сначала
скопировать его в `std::string`. А раз нужен `std::string`, то и параметром функции оптимальнее cделать `const std::string&`
и далее по цепочке, все параметры вновь станут `const std::string&`.
Далее, после инициализации строки, самая частая мутабельная операция с ними, скорее всего конкатенация строк, либо в виде просто
сложения строк, либо добавления строки к строке. И именно она легко может вызывать как неоптимальную производительность при неграмотном
использовании, так и оверхед по памяти, даже при грамотном использовании.
Рассмотрим простой код ( https://godbolt.org/z/odx7W1Pv7 )
```cpp
#include <string>
void some_outer_function(const std::string&);
void func(const std::string& s1, const std::string& s2) {
    std::string concat = s1 + s2 + "hello";
    some_outer_function(concat);
}
```
Как видим, и в clang, и в GCC создается несколько временных объектов, в которые последовательно перекладываются символы строк,
и как результат — мы получаем несколько лишних аллокаций для промежуточных буферов, символы из строк копируются несколько лишних
раз из промежуточных буферов. В идеале для лучшей производительности такой код нужно переписать так:
```cpp
#include <string>
void some_outer_function(const std::string&);
void func(const std::string& s1, const std::string& s2) {
    static const std::string_view hello = "hello";
    std::string concat;
    concat.reserve(s1.size() + s2.size() + hello.size());
    concat += s1;
    concat += s2;
    concat += hello;
  some_outer_function(concat);
}
```
К сожалению, пока ни один компилятор не оптимизирует первый простой код до уровня второго более оптимального кода, а писать
такой код каждый раз руками довольно неудобно. То есть опять приходится платить за то, чем не пользуешься.
Да и в этом случае вполне может возникнуть оверхед по памяти — операции добавления строки обычно во всех реализациях увеличивают
размер буфера строки не меньше, чем в два раза, считая, что скоро к строке могут снова что-нибудь добавить.
Поэтому если строку не планируется более модифицировать, но время её жизни ещё не подошло к концу (например, это поле
какого-либо класса), нужно ещё не забыть сделать на ней `shrink_to_fit`.
Между тем, часто основной сценарий использования строк — это как раз некая подготовка строки путём нескольких модификаций и конкатенаций,
а затем она где-то хранится, более не меняясь. При этом программист обычно знает, примерно какой размер строк ожидается в этом месте,
и мог бы выделить буфер для этих промежуточных модификаций прямо на стеке, прибегая к динамической аллокации только при превышении
размера этого буфера. Однако с текущей реализацией строк это сделать довольно проблематично, либо неудобно.
Подытожим, что имеем на данный момент:
- «Из коробки» в С++ для работы со строками сейчас имеется `std::string`.
- Строки подразумеваются мутабельными, что приводит к обязательному копированию всех символов строки при инициализации и
копировании объектов строк.
- Соответственно, не имеем возможности быстрого копирования строк, даже если не планируем потом менять копию.
- Конкатенация нескольких строк — задача, могущая выполнятся неоптимально, приводить к оверхеду по памяти, написать оптимальный код сложно.
- Есть костыль для иммутабельных строк в виде `std::string_view`, однако он не решает вопросы владения строкой, поэтому по сути
годится только как тип для передачи параметров в функции, не меняющие строки, с оговоркой, что не может использоваться в функциях,
вызывающих C-API, так как не даёт гарантий нуль-терминированности.
- Ну и к `std::string` есть вопросы, что несмотря на то, что это класс для строк, собственно для работы со строками в нём крайне куцый
функционал по сравнению с тем, к чему привыкли в других языках — к примеру нет замены подстрок по шаблону (в других языках это обычно
replace, но в С++ эта функция делает совершенно другое), trim, split, join, upper, lower и т. п.
Эти функции приходится каждый раз писать самому, и не факт, что у всех это получится оптимально.
Надеюсь, после этого небольшого вступления вам будет более понятно, какие проблемы я решал своей строковой библиотекой и каким образом.
## Библиотека simstr
Собственно, нельзя сказать, что «я свелосипедил свою реализацию класса для строк».
Как я ранее показал, сложно, а то и даже невозможно написать один единый строковый класс, хорошо подходящий для всех сценариев
использования. Именно поэтому у меня не строковый класс, а строковая библиотека, которая содержит несколько разных строковых типов,
от более простых к более сложным, каждый из которых имеет свои сильные и слабые стороны, и пользователю нужно грамотно подходить к
вопросу, какой из этих классов в каком случае стоит использовать.
Саму библиотеку я начал потихоньку разрабатывать ещё в 2011-2012 годах, когда у нас уже появилась семантика перемещения, но ещё
не было std::string_view. Однако сейчас минимальная версия стандарта для работы библиотеки: **C++20** используются концепты и \<format\>.
Сначала я расскажу о классах библиотеки для самих строк, а потом о том, как в ней оптимально решается задача конкатенации строк.
Несколько общих моментов:
- Все классы для работы со строками шаблонизированы типом символов, но подразумевается, что символы могут быть char, char16_t,
char32_t, wchar_t.
- Все строки имеют явную длину.
- Классы владельцы строк хранят их с завершающим нулем в конце, который не входит в длину строки.
- В самой строке могут содержаться нулевые символы, все алгоритмы работают только через длину строки, не обращая на них внимания.
- Классы владельцы строк могут инициализироваться строками другого типа символов, выполняя конвертацию между UTF-8, UTF-16, UTF-32.
- Для смены регистра символов и сравнения строк без учёта регистра используются встроенные таблицы для первой плоскости юникода
(до 0xFFFF). Строки считаются представленными в кодировке UTF-8, UTF-16, UTF-32 соответственно.
Однако не делается нормализация строк и не обрабатываются ситуации, когда смена регистра символа приводит к изменению их количества.
Если вам нужна строгая работа с юникодом, используйте другие средства, например ICU.
### Классы строк.
#### Первый самый простой класс строки называется, естественно, `simple_str` :)
(simstr::simple_str)
Класс просто представляет собой указатель на начало константной строки и её длину, по сути то же самое, что `std::string_view`.
Предназначен для работы с иммутабельными строками, не владеющий ими, то есть вы должны сами озаботиться тем, что реальная строка,
представленная через `simple_str` жива во время его использования.
Реализует все строковые методы, не модифицирующие строку.
Алиасы:
- `ssa` для simple_str\<char\>
- `ssu` для simple_str\<char16_t\>
- `ssw` для simple_str\<wchar_t>
- `ssuu` для simple_str\<char32_t\>
Применяется в основном для передачи строк как параметр функций, не модифицирующих переданную строку, вместо `const std::string&`,
а также для локальных переменных при работе с частями строк.
#### Второй класс — `simple_str_nt`
(simstr::simple_str_nt)
По устройству и назначению совпадает с `simple_str`, но дает гарантии нуль-терминированности строки.
То есть если функции надо переданный параметр без изменений передать дальше как C-строку в какое то API, она должна использовать для
параметра тип `simple_str_nt`.
Все классы владеющих строк (simstr::sstring, simstr::lstring) могут быть преобразованы в `simple_str_nt`, так как хранят строки с завершающим нулём.
Это позволяет писать функции с единым типом параметра, принимающим на вход любой тип владеющих строковых объектов.
Алиасы:
- `stra` для simple_str_nt\<char>
- `stru` для simple_str_nt\<char16_t>
- `strw` для simple_str_nt\<wchar_t>
- `struu` для simple_str_nt\<char32_t>
Может инициализироваться строковыми литералами:
```cpp
stra text = "Text";
```
Длина в этом случае вычисляется сразу при компиляции. Аналогично `simple_str_nt` создается с помощью `operator""_ss`:
```cpp
stringa result = "Count: "_ss + count;
```
#### Класс sstring (shared string).
(simstr::sstring)
Класс, могущий хранить иммутабельную строку.
То есть ему можно присвоить некую строку только целиком, модифицировать символы строки нельзя.
Владеет строкой, управляет памятью для символов строки.
Хранит со строками завершающий нуль, и может быть источником для `simple_str_nt`, для передачи в C-API.
Так же, как и `simple_str`, реализует все методы, не модифицирующие строку.
Алиасы:
- `stringa` для sstring\<char>
- `stringu` для sstring\<char16_t>
- `stringw` для sstring\<wchar_t>
- `stringuu` для sstring\<char32_t>
То, что хранимая строка иммутабельна, позволяет применить ряд оптимизаций:
- Для строк, не подходящих для SSO, использует общий разделяемый буфер с атомарным счётчиком ссылок.
Позволяет быстро копировать строку без необходимости блокировок доступа к содержимому буфера.
- Нет необходимости хранить размер буфера (capacity) — всё равно мы ничего не дописываем в буфер.
- Позволяет просто ссылаться на литералы программы, не копируя их символы в какой-либо буфер:
```cpp
stringa str = "Hello!"; // Ничего не стоит, не копирует байты строки
stringa ltr = stra{"Hello!"}; // А вот тут копирует байты строки в ltr
```
Также в классе применяется **SSO** Small String Optimization.
Короткие строки помещаются внутри самого объекта во внутренний буфер.
Размеры:
Для 64 бит:
- `stringa` класс 24 байта, SSO до 23 символов.
- `stringu` класс 32 байта, SSO до 15 символов.
- `stringuu` класс 32 байта, SSO до 7 символов.
Для 32 бит:
- `stringa` класс 16 байт, SSO до 15 символов.
- `stringu` класс 24 байта, SSO до 11 символов.
- `stringuu` класс 24 байта, SSO до 5 символов.
#### Класс lstring<K, N, forShared> (local string)
(simstr::lstring)
Класс, хранящий строку и позволяющий её модифицировать.
Владеет строкой, управляет памятью для символов строки.
Хранит со строками завершающий нуль, и может быть источником для `simple_str_nt`, для передачи в C-API.
Как и все остальные классы, реализует все методы, не модифицирующие строку.
В качестве `N` в параметре шаблона задаётся размер внутреннего буфера для хранения символов.
Строки длиной до N символов хранятся внутри объекта, а при превышении этого количества — аллоцируется динамический буфер,
в который сохраняются символы. При копировании объекта все символы также всегда копируются.
Если `forShare` == true и символы не помещаются в локальный буфер, то динамический буфер создается с дополнительным местом,
так чтобы совпадать по структуре с буфером `sstring`. Тогда при перемещении `lstring` в `sstring` переместится только указатель
на буфер, без излишнего копирования символов.
Этот класс удобен для работы со строками как локальная переменная на стеке.
Обычно мы предполагаем примерный размер строк, с котороми будем работать, и можем создать локальную строку с буфером на стеке,
и работать с ней. При этом не опасаясь переполнения буфера, так как в этом случае строка переключится на динамический буфер.
Алиасы:
- `lstringa<N=16>` для lsrting\<char, N, false>
- `lstringu<N=16>` для lsrting\<char16_t, N, false>
- `lstringw<N=16>` для lsrting\<wchar_t, N, false>
- `lstringuu<N=16>` для lsrting\<char32_t, N, false>
- `lstringsa<N=16>` для lsrting\<char, N, true>
- `lstringsu<N=16>` для lsrting\<char16_t, N, true>
- `lstringsw<N=16>` для lsrting\<wchar_t, N, true>
- `lstringsuu<N=16>` для lsrting\<char32_t, N, true>
Небольшой пример использования с пояснениями:
```cpp
#ifdef _WIN32
const char path_separator = '\\';
#else
const size_t MAX_PATH = 260;
const char path_separator = '/';
#endif
auto get_current_dir() {
#ifdef _WIN32
    /* заполняем буфер wchar_t строки lstringw<MAX_PATH> из GetCurrentDirectoryW с возможным
увеличением буфера и конвертируем в ut8 char. В конструкторе используется то, что появилось
только в С++23 как `resize_and_overwrite`, а у нас было изначально :) */
    lstringa<MAX_PATH> path{lstringw<MAX_PATH>{ [](auto p, auto s) { return GetCurrentDirectoryW(DWORD(s + 1), p); }}};
    /* Эта одна строчка делает примерно то же самое, что и вот такой код.
typedef struct lstringa_MAX_PATH_t {
char* data;
size_t length;
size_t capacity;
char local_buffer[MAX_PATH + 1];
} lstringa_MAX_PATH;
lstringa_MAX_PATH* get_current_dir(lstringa_MAX_PATH* result) {
    wchar_t buffer[MAX_PATH + 1], *buf = buffer;
    DWORD size = sizeof(buffer) / sizeof(wchar_t), lengthOfpath;
    for (;;) {
// Возвращает либо количество скопированных символов без учёта завершающего нуля,
// либо если буфер мал, то нужный размер буфера вместе с завершающим нулём
        DWORD ret = GetCurrentDirectoryW(size, buf);
        if (ret < size) {
// Влезло в буфер, хотя в Windows пути могут быть и длиннее, чем MAX_PATH, если начинаются с \\?\
// https://learn.microsoft.com/ru-ru/windows/win32/fileio/maximum-file-path-limitation?tabs=registry
            lenOfpath = ret;
            break;
        }
        size = ret;
        if (buf != buffer)
            free(buf);
        buf = malloc(size);
    }
    utf16toUtf8(buf, lengthOfPath, result);
    if (buf != buffer)
        free(buf);
return result;
}
    */
#else
    lstringa<MAX_PATH> path{ [](char* p, size_t s) {
        const char* res = getcwd(p, s + 1);
        if (res) {
            return stra{res}.length(); // Возвращаем длину строки
        }
        if (errno == ERANGE) // Не влезло в буфер, попробуем в два раза больше
            return s * 2;
        return 0ul;
    }};
#endif
// Удостоверимся, что строка будет заканчиваться разделителем директорий
    if (!path.length() || path.at(-1) != path_separator) {
        path += e_c(1, path_separator);
    }
    return path;
}
stringa build_full_path(ssa fileName) {
    return get_current_dir() + fileName + ".txt";
    /*
    Здесь сначала на стеке создастся временный объект lstringa<MAX_PATH> для вызова get_current_dir.
    Функция get_current_dir заполнит его названием текущего каталога.
    В 99.9% случаев для этого хватит локального буфера на стеке.
    После рассчитывается общая длина для результата: длина current_dir + длина fileName + 4.
    Определяется буфер для строки конечного результата - если длина меньше 24 — строка будет размещена прямо в stringa,
    иначе аллоцируется буфер для результирующей строки сразу нужного размера.
    Затем в буфер результирующей строки последовательно копируются символы из current_dir, file_name, ".txt";
    Ну и благодаря RVO - место для самого результата (stringa) - отводится в вызывающей функции,
    то есть никакого дополнительного копирования при возврате не будет.
    Таким образом, будет максимум всего две аллокации памяти (если current_dir не влезет в MAX_PATH),
или одна, если результирующая строка длиннее 23 символов, при этом эта аллокация будет сразу нужного размера.
    */
}
```
В этом примере вы наверняка заметили, как конкатенируются строки и задались вопросом — как же при двух сложениях длина всего результата считалась всего один раз, чтобы выделить необходимое место сразу, без промежуточных буферов?
Ответ на этот вопрос:
### Строковые выражения
Дело в том, что в библиотеке нет сложения строковых объектов как такового. Сложение выполняется для «строковых выражений».
*Строковое выражение* — это любой объект произвольного типа, имеющий функции `length` и `place`.
Функция `length` возвращает длину строки, функция `place` помещает символы строки в переданный ей буфер.
Любая владеющая строка (simstr::sstring, simstr::lstring) может инициализироваться строковым выражением — она запрашивает у него длину,
выделяет место для хранения символов, и передает это место строковому выражению, вызывая его функцию place.
Для строковых выражений определена шаблонная функция сложения:
```cpp
template<StrExpr A, StrExprForType<typename A::symb_type> B>
inline auto operator + (const A& a, const B& b) {
    return strexprjoin<A, B>{a, b};
}
```
`strexprjoin` шаблонный тип, который сам является строковым выражением.
В себе он хранит ссылки на два переданных ему строковых выражения.
При запросе длины он выдает сумму длин двух строковых выражений, а при размещении символов — сначала размещает
в переданном буфере первое выражение, затем второе.
```cpp
template<StrExpr A, StrExprForType<typename A::symb_type> B>
struct strexprjoin {
    using symb_type = typename A::symb_type;
    const A& a;
    const B& b;
    constexpr strexprjoin(const A& a_, const B& b_) : a(a_), b(b_){}
    constexpr size_t length() const noexcept { return a.length() + b.length(); }
    constexpr symb_type* place(symb_type* p) const noexcept { return b.place(a.place(p)); }
};
```
Таким образом, операция сложения нескольких строковых выражений создает объект, также являющийся строковым выражением,
который рекурсивно хранит ссылки на слагаемые части, каждая из которых знает свой размер и умеет размещать себя
в буфере результата. А чтобы получить готовый результат сложения, это выражение надо "материализовать", то есть
присвоить любому владеющему стровому объекту, который выделит всю память под результат за один раз и запустит
размещение символов в этой памяти.
Все строковые типы библиотеки сами являются строковыми выражениями, то есть могут служить слагаемыми в конкатенациях
строковых выражений.
Также `operator+` определён для строковых выражений и строковых литералов, строковых выражений и чисел (числа конвертируются
в десятичное представление), а также вы можете сами добавить желаемые типы.
Пример:
```cpp
stringa text = header + " count=" + count + ", done";
```
Существует несколько типов строковых выражений "из коробки", для выполнения различных операций со строками:
#### expr_spaces<ТипСимвола, КоличествоСимволов, Символ = ' '>{}
Выдает строку длиной КоличествоСимволов, заполненную заданным символом. Количество символов и символ - константы времени
компиляции. Для некоторых случаев есть сокращенная запись:
e_spca(КоличествоСимволов) - строка char пробелов
e_spcw(КоличествоСимволов) - строка w_char пробелов
#### expr_pad<ТипСимвола>{КоличествоСимволов, Символ = ' '}
Выдает строку длиной КоличествоСимволов, заполненную заданным символом.
Количество символов и символ могут задаваться в рантайме. Сокращенная запись:
e_c(КоличествоСимволов, Символ)
#### e_choice(bool Condition, StrExpr1, StrExpr2)
Если Condition == true, результат будет равен StrExpr1, иначе StrExpr2.
#### e_if(bool Condition, StrExpr1)
Если Condition == true, результат будет равен StrExpr1, иначе пустая строка.
#### expr_num<ТипСимвола>(ЦелоеЧисло)
Конвертирует число в десятичное представление. Редко используется, так как для строковых выражений и чисел
переопределен оператор "+", и число можно просто написать как `text + number`;
#### expr_real<ТипСимвола>(ВещественноеЧисло)
конвертирует число в десятичное представление. Редко используется, так как для строковых выражений и чисел
переопределен оператор "+", и число можно просто написать как `text + number`;
#### e_join<bool ПослеПоследнего = false, bool ТолькоНеПустые = false>(контейнер, "Разделитель")
Конкатенирует все строки в контейнере, используя разделитель. Если ПослеПоследнего == true,
то разделитель добавляется и после последнего элемента контейнера, иначе только между элементами.
Если ТолькоНеПустые == true, то пустые строки пропускаются без добавления разделителя.
#### e_repl(ИсходнаяСтрока, "Искать", "Заменять")
Заменяет в исходной строке вхождения "Искать" на "Заменять".
Шаблоны поиска и замены - строковые литералы времени компиляции.
#### expr_replaced<ТипСимвола>{ИсходнаяСтрока, Искать, Заменять}
Заменяет в исходной строке вхождения Искать на Заменять.
Шаблоны поиска и замены - могут быть любыми строковыми объектами в рантайме.
#### empty_expr<ТипСимвола>
Выдает пустую строку. Сокращённая запись — eea, eeu, eew, eeuu. Применяется если формирование строки начинается с числа и строкового литерала:
```cpp
str = eea + count + " times.";
```
так как оператор сложения определён только для сложения строкового выражения и числа.
Также замечу, что существует `operator""_ss`, который превращает строковый литерал в объект `simple_str_nt`, который уже является строковым выражением:
```cpp
str = "Count = "_ss + count;
...
str = count + " times."_ss;
```
#### Свои строковые выражения
Вы можете сами создавать свои типы строковых выражений для оптимального формирования строк в нужных вам целях и алгоритмах.
Для этого просто создайте тип с методами `length`, `place` и `typename symb_type`.
Примеры создания и использования из реальных проектов:
```cpp
/* Сформировать строку в JSON формате, в 16 битных символах */
struct expr_json_str {
    using symb_type = u16s;
    ssu text;
    size_t l;
    size_t length() const noexcept {
        return l;
    }
    u16s* place(u16s* ptr) const noexcept;
    expr_json_str(ssu t);
};
inline expr_json_str::expr_json_str(ssu t) : text(t) {
    const u16s* ptr = text.symbols();
    size_t add = 0;
    for (size_t i = 0; i < text.length(); i++) {
        switch (*ptr++) {
        case '\b':
        case '\f':
        case '\r':
        case '\n':
        case '\t':
        case '\"':
        case '\\':
            add++;
        }
    }
    l = text.len + add;
}
inline u16s* expr_json_str::place(u16s* ptr) const noexcept {
    const u16s *r = text.symbols();
    size_t lenOfText = text.length(), lenOfTail = l;
    while (lenOfTail > lenOfText) {
        u16s s = *r++;
        switch (s) {
        case '\b':
            *ptr++ = '\\';
            *ptr++ = 'b';
            lenOfTail--;
            break;
        case '\f':
            *ptr++ = '\\';
            *ptr++ = 'f';
            lenOfTail--;
            break;
        case '\r':
            *ptr++ = '\\';
            *ptr++ = 'r';
            lenOfTail--;
            break;
        case '\n':
            *ptr++ = '\\';
            *ptr++ = 'n';
            lenOfTail--;
            break;
        case '\t':
            *ptr++ = '\\';
            *ptr++ = 't';
            lenOfTail--;
            break;
        case '\"':
            *ptr++ = '\\';
            *ptr++ = '\"';
            lenOfTail--;
            break;
        case '\\':
            *ptr++ = '\\';
            *ptr++ = '\\';
            lenOfTail--;
            break;
        default:
            *ptr++ = s;
            break;
        }
        lenOfTail--;
        lenOfText--;
    }
    if (lenOfTail) {
        std::char_traits<u16s>::copy(ptr, r, lenOfTail);
        ptr += lenOfTail;
    }
    return ptr;
}
```
Использование:
```cpp
........
chunked_string_builder<u16s> vtText;
........
vtText << uR"({"#type":"jxs:string","#value":")" + expr_json_str(name) + u"\"}";
.......
```
Ещё пример
```cpp
/* Нужно сформировать бинарные данные в BASE64 формате, в 16 битных символах */
struct expr_str_base64 {
    using symb_type = u16s;
    ssa text;
    size_t length() const noexcept {
        return (text.len + 2) / 3 * 4;
    }
    u16s* place(u16s* ptr) const noexcept;
    expr_str_base64(ssa t) : text(t) {}
};
inline u16s* expr_str_base64::place(u16s* ptr) const noexcept {
    static constexpr u8s alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    const unsigned char* t = (const unsigned char*)text.str;
    size_t i = 0;
    if (text.len > 2) {
        for (; i < text.len - 2; i += 3) {
            *ptr++ = alphabet[(t[i] >> 2) & 0x3F];
            *ptr++ = alphabet[((t[i] & 0x3) << 4) | ((int)(t[i + 1] & 0xF0) >> 4)];
            *ptr++ = alphabet[((t[i + 1] & 0xF) << 2) | ((int)(t[i + 2] & 0xC0) >> 6)];
            *ptr++ = alphabet[t[i + 2] & 0x3F];
        }
    }
    if (i < text.len) {
        *ptr++ = alphabet[(t[i] >> 2) & 0x3F];
        if (i == (text.len - 1)) {
            *ptr++ = alphabet[((t[i] & 0x3) << 4)];
            *ptr++ = '=';
        } else {
            *ptr++ = alphabet[((t[i] & 0x3) << 4) | ((int)(t[i + 1] & 0xF0) >> 4)];
            *ptr++ = alphabet[((t[i + 1] & 0xF) << 2)];
        }
        *ptr++ = '=';
    }
    return ptr;
}
```
Использование:
```cpp
......
chunked_string_builder<u16s> vtText;
......
vtText << u"{\"#\",87126200-3e98-44e0-b931-ccb1d7edc497,{1,{#base64:" + expr_str_base64(v) + u"}}},";
......
```
И ещё
```cpp
/* Нужно преобразовать tm в строку даты/времени в 16-битных символах */
struct expr_str_tm {
    using symb_type = u16s;
    const tm& t;
    size_t length() const noexcept {
        return 19;
    }
    u16s* place(u16s* ptr) const noexcept;
    expr_str_tm(const tm& _t) : t(_t) {}
};
inline u16s* expr_str_tm::place(u16s* ptr) const noexcept {
    if constexpr (sizeof(wchar_t) == 2) {
        // Под Windows можно сразу форматнуть строку в нужный буфер
        std::swprintf((wchar_t*)ptr, 20, L"%04i-%02i-%02i %02i:%02i:%02i", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
t.tm_hour, t.tm_min, t.tm_sec);
    } else {
        // Сначала форматнём в промежуточный буфер, потом скопируем в результат
        char buf[20];
        std::snprintf(buf, 20, "%04i-%02i-%02i %02i:%02i:%02i", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour,
t.tm_min, t.tm_sec);
        for (unsigned i = 0; i < 19; i++) {
            ptr[i] = buf[i];
        }
    }
    return ptr + 19;
}
```
Использование
```cpp
......
bool makeBind(SqliteQuery& query, tVariant& param, unsigned paramNum) {
    switch (param.vt) {
......
    case VTYPE_DATE:
        query.bind(paramNum, lstringu<30>{expr_str_tm{winDateToTm(param.date)}}.to_str());
        break;
    case VTYPE_TM:
        query.bind(paramNum, lstringu<30>{expr_str_tm{param.tmVal}}.to_str());
        break;
......
```
ВНИМАНИЕ: обычно поля в объектах строковых выражений являются ссылками на исходные данные.
И ссылки эти почти всегда ведут на локальные или временные объекты. Поэтому крайне рискованно возвращать строковые выражения
из функций — надо сто раз проверить, что в них не попали ссылки на локальные или временные переменные.
Возьмите за правило — можно легко передавать строковые выражения в функции, и опасно возвращать их из функций.
Лучше при возврате материализовать строковое выражение в строковый объект, содержащий итоговую строку.
При желании тип возвращаемой строки можно задать шаблонным параметром.
### Класс chunked_string_builder
Предназначен для конкатенации множества строк.
Когда вам нужно последовательно формировать длинный текст из множества небольших кусочков (например, формируете html ответ
и т. п.) - последовательно складывать всё в один строковый объект крайне неоптимально — будет много переаллокаций и
перекопирования уже накопленных символов. В этом случае удобно использовать chunked_string_builder — всё, что он умеет,
это прибавлять строку к накопленным символам. Однако делает он это не в единый последовательный буфер памяти, а в отдельные
буфера, не меньше чем заданное выравнивание. При заполнении очередного буфера он просто создает ещё один буфер и продолжает
складывать данные в него.
То есть допустим вы задали выравнивание 1024.
Добавили несколько строк, заполнили буфер на 100 символов. И добавляете строку длинной 3000 символов.
При этом 924 символа скопируются в первый буфер, заполнив его до конца.
Для оставшихся 2076 создастся буфер размером 3072 символа, и они скопируются в него, в нём останется место для 996 символов.
Так последовательно каждый буфер заполняется до конца, и имеет размер кратный заданному выравниванию.
Таким образом избегаются переаллокации и перекопирование обработанных символов.
После окончательного заполнения вы можете работать с накопленными данными — либо слить все буфера в одну последовательную
строку (размер для буфера которой вы теперь уже знаете), либо перебирать их по отдельности, например, посылая эти буфера
в сеть. Либо последовательно копируя данные в буфер заданного размера.

67
for_debug/readme.md Normal file
View File

@ -0,0 +1,67 @@
# Объекты simstr в отладчиках
Для более удобного отображения объектов simstr в отладчиках msvc и gdb подготовлено два файла:
simstr.natvis - для использования в отладчике MSVC, и simstr_pretty_print.py для работы с gdb.
# Объекты simstr в отладчиках
Если вы работаете в MS Visual Studio - просто добавьте simstr.natvis в свой проект.
# Объекты simstr в Visual Studio Code
## При работе в gdb
В конфигурации отладчика необходимо добавить следующие строки:
```
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Enable pretty-printing for simstr",
"text": "source ${workspaceFolder}/for_debug/simstr_pretty_print.py",
"ignoreFailures": true
}
]
```
После этого в отладчике будут удобно отображаться объекты simstr.
Скрипт инспектирует переменные этих типов и выдает для них текстовое описание, отображающее их
содержимое в удобном виде. В первой строке отображается основная информация, видимая в окне
инспектирования переменных. При наведении указателя мыши на переменную в окне исходного кода
или на значении в окне инспектирования переменных во всплывающем тултипе будет показана
остальная информация.
Конфигурации отладчика располагаются в файле `.vscode/launch.json`.
Возможно, у вас также установлено расширение `CMake Tools`, которое позволяет выбирать целевой проект для запуска.
В этом случае настройки для подключения скрипта прописываются в `.vscode/settings.json`:
```
"cmake.debugConfig": {
"MIMode": "gdb",
"environment": [],
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"text": "source ${workspaceFolder}/for_debug/simstr_pretty_print.py",
"description": "pretty print simstr",
"ignoreFailures": true
}
]
}
```
Если же в Visual Studio Code вы работаете с отладчиком MSVC, то есть в launch.json `"type": "cppvsdbg"` то настройка другая:
```
"configurations": [
{
.....
"type": "cppvsdbg",
....
"visualizerFile": "${workspaceFolder}/for_debug/simstr.natvis"
},
...
```

33
for_debug/simstr.natvis Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Файл с описанием визуализации simstr строк для Visual Studio -->
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="simstr::simple_str&lt;*&gt;">
<DisplayString Condition="0xCCCCCCCC==(unsigned)str">[unknown]</DisplayString>
<DisplayString Condition="sizeof($T1)==1">l={len}, {str,[len]nas8}</DisplayString>
<DisplayString Condition="sizeof($T1)==2">l={len}, {str,[len]nasu}</DisplayString>
<DisplayString Condition="sizeof($T1)==4">l={len}, {str,[len]nas32}</DisplayString>
<DisplayString>[unknown]</DisplayString>
</Type>
<Type Name="simstr::sstring&lt;*&gt;">
<DisplayString Condition="sizeof($T1)==1 &amp;&amp; type_ == 0">inplace, l={LocalCount - localRemain_}, {buf_,[LocalCount - localRemain_]nas8}</DisplayString>
<DisplayString Condition="sizeof($T1)==1 &amp;&amp; type_ == 1">literal, l={bigLen_}, {cstr_,[bigLen_]nas8}</DisplayString>
<DisplayString Condition="sizeof($T1)==1 &amp;&amp; type_ == 2">shared, l={bigLen_}, ref={((SharedStringData&lt;$T1&gt;*)sstr_)[-1].ref_}, {sstr_,[bigLen_]nas8}</DisplayString>
<DisplayString Condition="sizeof($T1)==2 &amp;&amp; type_ == 0">inplace, l={LocalCount - localRemain_}, {buf_,[LocalCount - localRemain_]nasu}</DisplayString>
<DisplayString Condition="sizeof($T1)==2 &amp;&amp; type_ == 1">literal, l={bigLen_}, {cstr_,[bigLen_]nasu}</DisplayString>
<DisplayString Condition="sizeof($T1)==2 &amp;&amp; type_ == 2">shared, l={bigLen_}, ref={((SharedStringData&lt;$T1&gt;*)sstr_)[-1].ref_}, {sstr_,[bigLen_]nasu}</DisplayString>
<DisplayString Condition="sizeof($T1)==4 &amp;&amp; type_ == 0">inplace, l={LocalCount - localRemain_}, {buf_,[LocalCount - localRemain_]nas32}</DisplayString>
<DisplayString Condition="sizeof($T1)==4 &amp;&amp; type_ == 1">literal, l={bigLen_}, {cstr_,[bigLen_]nas32}</DisplayString>
<DisplayString Condition="sizeof($T1)==4 &amp;&amp; type_ == 2">shared, l={bigLen_}, ref={((SharedStringData&lt;$T1&gt;*)sstr_)[-1].ref_}, {sstr_,[bigLen_]nas32}</DisplayString>
<DisplayString>[unknown]</DisplayString>
</Type>
<Type Name="simstr::lstring&lt;*&gt;">
<DisplayString Condition="0xCCCCCCCC==(unsigned)data_">[unknown]</DisplayString>
<DisplayString Condition="data_==local_ &amp;&amp; size_==0">empty, c={(int)LocalCapacity}</DisplayString>
<DisplayString Condition="sizeof($T1)==1 &amp;&amp; data_==local_">inplace, l={size_}, c={(int)LocalCapacity}, {data_,[size_]nas8}</DisplayString>
<DisplayString Condition="sizeof($T1)==1 &amp;&amp; data_!=local_">outplace, l={size_}, c={capacity_}, {data_,[size_]nas8}</DisplayString>
<DisplayString Condition="sizeof($T1)==2 &amp;&amp; data_==local_">inplace, l={size_}, c={(int)LocalCapacity}, {data_,[size_]nasu}</DisplayString>
<DisplayString Condition="sizeof($T1)==2 &amp;&amp; data_!=local_">outplace, l={size_}, c={capacity_}, {data_,[size_]nasu}</DisplayString>
<DisplayString Condition="sizeof($T1)==4 &amp;&amp; data_==local_">inplace, l={size_}, c={(int)LocalCapacity}, {data_,[size_]nas32}</DisplayString>
<DisplayString Condition="sizeof($T1)==4 &amp;&amp; data_!=local_">outplace, l={size_}, c={capacity_}, {data_,[size_]nas32}</DisplayString>
</Type>
</AutoVisualizer>

View File

@ -0,0 +1,202 @@
# Скрипт для pretty printing simstr строк в gdb
#
import gdb
import itertools
import re
import sys, os, errno
from datetime import datetime
import gdb.printing
import gdb.types
def get_str_from_ptr(ptr, len, buffer_type = None, capacity = None, ref_count = None):
if len >= 0x10000000: # Скорее всего это не инициализированная переменная
return f'{ptr}\nLength: {len}'
if len > 64:
view_len = 64
append = ''
else:
view_len = len
append = ''
# lazy_string сама заключает строку в кавычки и в зависимости от типа переменной добавляет символ кодировки: "", u"", L"", U""
# Автоматически использует UTF-8. Для нулевой длины вначале добавляет адрес указателя
if hasattr (ptr, "lazy_string"):
# Преобразуем в обычную настоящую строку
res = str(ptr.lazy_string(length = view_len).value())
# Добавим многоточие
if append != '':
res = f'{res[:-1]}{append}"'
else:
res = f'"{ptr.string(length = view_len)}{append}"'
if len == 0 and res[0:2] == '0x':
# Для пустой строки вставляется адрес зачем-то, уберём его
res = res[res.index(' ') + 1:]
# Ещё и добавляет символы из строки, хотя длина 0
res = res[0 : res.index('"') + 1] + '"'
res += f'\nLength: {len}'
if not buffer_type is None:
res += f'\nString buffer: {buffer_type}'
if not capacity is None:
res += f'\nCapacity: {capacity}'
if not ref_count is None:
res += f'\nRef count: {ref_count}'
return res
class TypesInfo:
def __init__(self):
self.sstring_local_counts = {}
self.lstring_local_counts = {}
self.shared_data_type = gdb.lookup_type('simstr::SharedStringData<char>').pointer()
types_info = None
def get_types_info():
global types_info
if types_info is None:
types_info = TypesInfo()
return types_info
def ssa_printer(store, val):
return get_str_from_ptr(val['str'], val['len'])
def sstring_printer_init(store, type_name):
ti = get_types_info()
if type_name in ti.sstring_local_counts:
store.local_count = ti.sstring_local_counts[type_name]
else:
store.local_count = gdb.parse_and_eval(f'(int){type_name}::LocalCount')
ti.sstring_local_counts[type_name] = store.local_count
def sstring_printer(store, val):
buf_type = val['type_']
refs = None
if buf_type == 0:
buf_type = 'SSO inplace'
len = store.local_count - val['localRemain_']
ptr = val['buf_']
elif buf_type == 1:
buf_type = 'const literal'
len = val['bigLen_']
ptr = val['cstr_']
elif buf_type == 2:
buf_type = 'shared'
len = val['bigLen_']
ptr = val['sstr_']
refs = ptr.reinterpret_cast(get_types_info().shared_data_type)[-1]['ref_']['_M_i']
else:
return "<unknown>"
return get_str_from_ptr(ptr, len, buffer_type = buf_type, ref_count = refs)
def lstring_printer_init(store, type_name):
ti = get_types_info()
if type_name in ti.lstring_local_counts:
store.LocalCapacity = ti.lstring_local_counts[type_name]
else:
store.LocalCapacity = gdb.parse_and_eval(f'(int){type_name}::LocalCapacity')
ti.lstring_local_counts[type_name] = store.LocalCapacity
def lstring_printer(store, val):
ptr = val['data_']
len = val['size_']
buf = val['local_']
if ptr == buf:
buf_type = "inplace"
cap = store.LocalCapacity
else:
buf_type = "outer"
cap = val['capacity_']
return get_str_from_ptr(ptr, len, buffer_type = buf_type, capacity = cap)
class SimplePrinter:
"Print a value with stored function"
def __init__(self, typename, to_str, val, init):
self.val = val
self.func = to_str
if not init is None:
init(self, typename)
def to_string(self):
try:
return self.func(self, self.val)
except gdb.error as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
print(exc_type, fname, exc_tb.tb_lineno)
return "<gdb.error>"
except Exception as e:
print(f"Тип исключения: {type(e).__name__}, сообщение: {str(e)}")
return "<Exception>"
except:
print("Unexpected error:", sys.exc_info()[0])
return "<error>"
def get_basic_type(type):
# If it points to a reference, get the reference.
if type.code == gdb.TYPE_CODE_REF:
type = type.target()
# Get the unqualified type, stripped of typedefs.
type = type.unqualified().strip_typedefs()
return type.tag
class PrintersStore(object):
def __init__(self):
super(PrintersStore, self).__init__()
self.lookup = {}
self.compiled_rx = re.compile('^([a-zA-Z0-9_:]+)(<.*>)?$')
def add(self, name, creator):
if not self.compiled_rx.match(name):
raise ValueError('simstr programming error: "%s" does not match' % name)
self.lookup[name] = creator
def __call__(self, val):
typename = get_basic_type(val.type)
if not typename:
return None
match = self.compiled_rx.match(typename)
if not match:
return None
basename = match.group(1)
if basename in self.lookup:
if val.type.code == gdb.TYPE_CODE_REF:
if hasattr(gdb.Value,"referenced_value"):
val = val.referenced_value()
creator = self.lookup[basename]
return SimplePrinter(typename, creator[0], val, None if len(creator) == 1 else creator[1])
return None
printerStore = PrintersStore()
printer_list = {
"sstring": [sstring_printer, sstring_printer_init],
"tests::Tstringa": [sstring_printer, sstring_printer_init],
"lstring": [lstring_printer, lstring_printer_init],
"simple_str": [ssa_printer],
"simple_str_nt": [ssa_printer],
}
for name, func in printer_list.items():
printerStore.add("simstr::" + name, func)
gdb.pretty_printers.append(printerStore)
print("\n\nPrettify simstr strings loaded!!!\n\n")

View File

@ -0,0 +1,21 @@
/*
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
* ver. 1.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
uint16_t simpleUnicodeUpper(uint16_t c);
uint16_t simpleUnicodeLower(uint16_t c);
uint16_t simpleUnicodeFold(uint16_t c);
uint16_t simpleUnicodeTitle(uint16_t c);
uint16_t simpleUnicodeUnacc(uint16_t c, uint16_t** p, int* l);
#ifdef __cplusplus
}
#endif

6340
include/simstr/sstring.h Normal file

File diff suppressed because it is too large Load Diff

986
include/simstr/strexpr.h Normal file
View File

@ -0,0 +1,986 @@
/*
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
* ver. 1.0
* База для строковых конкатенаций через выражения времени компиляции
*/
#pragma once
#include <cstdlib>
#include <string>
#include <string_view>
#include <type_traits>
#include <concepts>
#include <utility>
/*!
* @brief Пространство имён для объектов библиотеки
*/
namespace simstr {
// Выводим типы для 16 и 32 битных символов в зависимости от размера wchar_t
inline constexpr bool wchar_is_u16 = sizeof(wchar_t) == 2;
using wchar_type = std::conditional<wchar_is_u16, char16_t, char32_t>::type;
inline wchar_type* to_w(wchar_t* p) {
return (reinterpret_cast<wchar_type*>(p));
}
inline const wchar_type* to_w(const wchar_t* p) {
return (reinterpret_cast<const wchar_type*>(p));
}
inline wchar_t* from_w(wchar_type* p) {
return (reinterpret_cast<wchar_t*>(p));
}
inline const wchar_t* from_w(const wchar_type* p) {
return (reinterpret_cast<const wchar_t*>(p));
}
using u8s = char;
using uws = wchar_t;
using u16s = char16_t;
using u32s = char32_t;
using uu8s = std::make_unsigned<u8s>::type;
template<typename K>
inline constexpr bool is_one_of_char_v = std::is_same_v<K, u8s> || std::is_same_v<K, wchar_t> || std::is_same_v<K, u16s> || std::is_same_v<K, u32s>;
template<typename K>
inline constexpr bool is_one_of_std_char_v = std::is_same_v<K, u8s> || std::is_same_v<K, wchar_t> || std::is_same_v<K, wchar_type>;
template<typename From>
requires (is_one_of_std_char_v<From>)
auto to_one_of_std_char(From* from) {
if constexpr (std::is_same_v<From, u8s> || std::is_same_v<From, wchar_t>) {
return from;
} else {
return from_w(from);
}
}
template<typename From>
requires (is_one_of_std_char_v<From>)
auto to_one_of_std_char(const From* from) {
if constexpr (std::is_same_v<From, u8s> || std::is_same_v<From, wchar_t>) {
return from;
} else {
return from_w(from);
}
}
/*
Вспомогательные шаблоны для определения строковых литералов.
Используются для того, чтобы в параметрах функций ограничивать типы строго как `const K(&)[N]`
Если пишем
template<size_t N>
void func(const char(&lit)[N]);
то в такую функцию можно будет передать не константный буфер, что может вызывать ошибку:
// Выделили место под символы
char buf[100];
// Как то наполнили буфер, допустим, до половины.
stringa text = buf;
Тут компилятор приведет buf из типа char[100] в тип const char[100] и вызовет конструктор
для строкового литерала, в text запишется просто указатель на buf и длина 100.
Поэтому такие параметры объявляем как
template<typename T, typename K = typename const_lit<T>::symb_type, size_t N = const_lit<T>::Count>
void func(T&& lit);
Тогда компилятор будет подставлять для T точный тип параметра без попыток привести тип к другому типу,
и выражение с параметром char[100] - не скомпилируется.
*/
template<typename T> struct const_lit; // sfinae отработает, так как не найдёт определения
// Для правильных типов параметров есть определение, в виде специализации шаблона
template<typename T, size_t N>
requires(is_one_of_char_v<T>)
struct const_lit<const T(&)[N]> {
using symb_type = T;
constexpr static size_t Count = N;
};
// Тут ещё дополнительно ограничиваем тип литерала
template<typename K, typename T> struct const_lit_for;
template<typename K, size_t N>
requires(is_one_of_char_v<K>)
struct const_lit_for<K, const K(&)[N]> {
constexpr static size_t Count = N;
};
template<typename K, size_t N>
class const_lit_to_array {
template<size_t Idx>
size_t find(K s) const {
if constexpr (Idx < N) {
return s == symbols_[Idx] ? Idx : find<Idx + 1>(s);
}
return -1;
}
template<size_t Idx>
bool exist(K s) const {
if constexpr (Idx < N) {
return s == symbols_[Idx] || exist<Idx + 1>(s);
}
return false;
}
public:
const K (&symbols_)[N + 1];
template<typename T, size_t M = const_lit_for<K, T>::Count> requires (M == N + 1)
constexpr const_lit_to_array(T&& s)
: symbols_(s) {}
constexpr bool contain(K s) const {
return exist<0>(s);
}
constexpr size_t index_of(K s) const {
return find<0>(s);
}
};
/*!
* @brief Базовая концепция строкового объекта.
* @tparam A - проверяемый тип
* @tparam K - тип символов
* @details В библиотеке для разных целей могут использоваться различные типы объектов строк.
* Мы считаем строковым объектом любой объект, поддерживающий методы:
* - `is_empty()`: возвращает, пуста ли строка.
* - `length()`: возвращает длину строки без нулевого терминатора.
* - `symbols()`: возвращает указатель на строку символов.
* - `typename symb_type`: задаёт тип символов строки
*/
template<typename A, typename K>
concept StrType = requires(const A& a) {
{ a.is_empty() } -> std::same_as<bool>;
{ a.length() } -> std::convertible_to<size_t>;
{ a.symbols() } -> std::same_as<const K*>;
} && std::is_same_v<typename std::remove_cvref_t<A>::symb_type, K>;
/*!
* @brief Строковые выражения
* @defgroup StrExprs Строковые выражения
* @details Все типы владеющих строк могут инициализироваться с помощью "строковых выражений"
* (по сути это вариант https://en.wikipedia.org/wiki/Expression_templates для строк).
* Строковое выражение - это объект произвольного типа, у которого имеются методы:
* - `size_t length() const`: выдает длину строки
* - `K* place(K*) const`: скопировать символы строки в предназначенный буфер и вернуть указатель за последним символом
* - `typename symb_type`: показывает, с каким типом символов он работает.
*
* При инициализации строковый объект запрашивает у строкового выражения его размер, выделяет необходимую память,
* и передает память строковому выражению, которое помещает символы в отведённый буфер.
*
* Все строковые объекты библиотеки сами являются строковыми выражениями, которые просто копирует исходную строку.
* В-основном строковые выражения используются для конкатенации или конвертации строк.
*
* Для всех строковых выражений определен @ref op_plus_str_expr "operator +", который из двух операндов создает новое строковое выражение
* simstr::strexprjoin, объединяющее два строковых выражения, и которое в методе `length` возвращает сумму `length` исходных операндов,
* а в методе `place` - размещает в буфер результата сначала первый операнд, потом второй.
* И так как этот оператор сам возвращает строковое выражение, то к нему снова можно применить `operator +`, формируя цепочку из нескольких
* строковых выражений, и в итоге "материализовать" последний получившийся объект, который сначала посчитает размер всей общей памяти
* для конечного результата, а затем разместит вложенные подвыражения в один буфер.
*
* Также `operator +` определён для строковых выражений и строковых литералов, строковых выражений и чисел
* (числа конвертируются в десятичное представление), а также вы можете сами добавить желаемые типы строковых выражений.
* Пример:
* ```cpp
* stringa text = header + ", count = " + count + ", done";
* ```
* Существует несколько типов строковых выражений "из коробки", для выполнения различных операций со строками
* - `expr_spaces<ТипСимвола, КоличествоСимволов, Символ>{}`: выдает строку длиной КоличествоСимволов,
* заполненную заданным символом. Количество символов и символ - константы времени компиляции.
* Для некоторых случаев есть сокращенная запись:
* - `e_spca<КоличествоСимволов>()`: строка char пробелов
* - `e_spcw<КоличествоСимволов>()`: строка w_char пробелов
* - `expr_pad<ТипСимвола>{КоличествоСимволов, Символ}`: выдает строку длинной КоличествоСимволов,
* заполненную заданным символом. Количество символов и символ могут задаваться в рантайме.
* Сокращенная запись: `e_c(КоличествоСимволов, Символ)`
* - `e_choice(bool Condition, StrExpr1, StrExpr2)`: если Condition == true, результат будет равен StrExpr1, иначе StrExpr2
* - `e_num<ТипСимвола>(ЦелоеЧисло)`: конвертирует число в десятичное представление. Редко используется, так как
* для строковых выражений и чисел переопределен оператор "+", и число можно просто написать как text + number;
* - `e_real<ТипСимвола>(ВещественноеЧисло)`: конвертирует число в десятичное представление. Редко используется, так как
* для строковых выражений и чисел переопределен оператор "+", и число можно просто написать как `text + number`;
* - `e_join<bool ПослеПоследнего = false, bool ПропускатьПустые = false>(контейнер, "Разделитель")`: конкатенирует все строки
* в контейнере, используя разделитель.
* Если `ПослеПоследнего == true`, то разделитель добавляется и после последнего элемента контейнера, иначе только
* между элементами.
* Если `ПропускатьПустые == true`, то пустые строки не добавляют разделитель, иначе для каждой пустой строки
* тоже вставляется разделитель
* - `e_repl(ИсходнаяСтрока, "Искать", "Заменять")`: заменяет в исходной строке вхождения "Искать" на "Заменять".
* Шаблоны поиска и замены - строковые литералы времени компиляции.
* - `expr_replaced<ТипСимвола>{ИсходнаяСтрока, Искать, Заменять}`: заменяет в исходной строке вхождения Искать на Заменять.
* Шаблоны поиска и замены - могут быть любыми строковыми объектами в рантайме.
*
* и т.д. и т.п.
*/
/*!
* @brief Концепт "Строковых выражений"
* @ingroup StrExprs
* @details Это концепт, проверяющий, является ли тип "строковым выражением".
*/
template<typename A>
concept StrExpr = requires(const A& a) {
typename A::symb_type;
{ a.length() } -> std::convertible_to<size_t>;
{ a.place(std::declval<typename A::symb_type*>()) } -> std::same_as<typename A::symb_type*>;
};
/*!
* @brief Концепт строкового выражения заданного типа символов
* @ingroup StrExprs
* @tparam A - проверяемый тип
* @tparam K - проверяемый тип символов
* @details Служит для задания ограничения к строковому выражению по типу символов
*/
template<typename A, typename K>
concept StrExprForType = StrExpr<A> && std::is_same_v<K, typename A::symb_type>;
/*
* Шаблонные классы для создания строковых выражений из нескольких источников
* Благодаря компиляторно-шаблонной "магии" позволяют максимально эффективно
* получать результирующую строку - сначала вычисляется длина результирующей строки,
* потом один раз выделяется память для результата, после символы помещаются в
* выделенную память.
* Для конкатенация двух объектов строковых выражений в один
*/
/*!
* @brief Шаблонный класс для конкатенации двух строковых выражений в одно с помощью `operator +`
* @ingroup StrExprs
* @tparam A - Тип первого операнда
* @tparam B - Тип второго операнда
* @details Этот объект запоминает ссылки на два операнда операции сложения.
* Когда у него запрашивают необходимый для результата размер буфера - он выдает сумму длин своих операндов.
* Когда запрашивают размещение символов в буфере - размещает сначала первый операнд, затем второй.
*/
template<StrExpr A, StrExprForType<typename A::symb_type> B>
struct strexprjoin {
using symb_type = typename A::symb_type;
const A& a;
const B& b;
constexpr strexprjoin(const A& a_, const B& b_) : a(a_), b(b_){}
constexpr size_t length() const noexcept {
return a.length() + b.length();
}
constexpr symb_type* place(symb_type* p) const noexcept {
return b.place(a.place(p));
}
constexpr symb_type* len_and_place(symb_type* p) const noexcept {
a.length();
b.length();
return place(p);
}
};
/*!
* @brief Оператор сложения двух произвольных строковых выражения для одинакового типа символов
* @ingroup StrExprs
* @anchor op_plus_str_expr
* @param a - первое строковое выражение
* @param b - второе строковое выражение
* @return strexprjoin<A, B>, строковое выражение, генерирующее объединение переданных выражений
* @details Когда складываются два объекта - строковых выражения, один типа `A`, другой типа `B`,
* мы возвращаем объект типа strexprjoin<A, B>, который содержит ссылки на два этих операнда.
* А сам объект strexprjoin<A, B> тоже в свою очередь является строковым выражением, и может участвовать
* в следующих операциях сложения. Таким образом формируется "дерево" из исходных строковых
* выражений, которое потом за один вызов "материализуется" в конечный результат.
*/
template<StrExpr A, StrExprForType<typename A::symb_type> B>
inline auto operator+(const A& a, const B& b) {
return strexprjoin<A, B>{a, b};
}
/*!
* @brief Конкатенация ссылки на строковое выражение и значения строкового выражения
* @ingroup StrExprs
* @tparam A - Тип одного строкового выражения
* @tparam B - Тип другого строкового выражения
* @tparam last - какое из них первое
* @details Чтобы иметь возможность складывать строковое выражение с операндами, не являющимися строковым выражением,
* нам нужно иметь возможность вернуть из `operator+` объект, который сохранит ссылку на операнд, являющийся строковым
* выражением, а для не строкового операнда будет иметь поле со строковым выражением, обрабатывающим второй операнд.
* Можно посмотреть пример в simstr::operator+<StrExpr A, FromIntNumber T>()
*/
template<StrExpr A, StrExprForType<typename A::symb_type> B, bool last = true>
struct strexprjoin_c {
using symb_type = typename A::symb_type;
const A& a;
B b;
template<typename... Args>
constexpr strexprjoin_c(const A& a_, Args&&... args_) : a(a_), b(std::forward<Args>(args_)...) {}
constexpr size_t length() const noexcept {
return a.length() + b.length();
}
constexpr symb_type* place(symb_type* p) const noexcept {
if constexpr (last) {
return b.place(a.place(p));
} else {
return a.place(b.place(p));
}
}
constexpr symb_type* len_and_place(symb_type* p) const noexcept {
a.length();
b.length();
return place(p);
}
};
template<typename T, typename K = void, typename... Types>
struct is_one_of_type {
static constexpr bool value = std::is_same_v<T, K> || is_one_of_type<T, Types...>::value;
};
template<typename T>
struct is_one_of_type<T, void> : std::false_type {};
/*!
* @brief "Пустое" строковое выражение
* @ingroup StrExprs
* @tparam K - тип символа
* @details Простое строковое выражение, генерирующее пустую строку.
* В основном применяется в функции e_choice, когда одна из веток должна вернуть пустую строку.
* Либо для начала операции сложения строковых выражений, когда другой операнд не является строковым выражением,
* но для него есть оператор сложения со строковыми выражениями.
* Для удобства уже определены константные объекты этого типа для разных видов символов:
* - eea для пустой строки char
* - eew для пустой строки wchar_t
* - eeu для пустой строки char16_t
* - eeuu для пустой строки char32_t
*
* Пример:
* ```cpp
* result = shost + e_choice(sserv.is_empty(), eea, ":" + sserv);
* ```
*
* ```cpp
* result += "E" + e_choice(adjusted_exponent > 0, "+"_ss, eea) + adjusted_exponent;
* ```
*/
template<typename K>
struct empty_expr {
using symb_type = K;
constexpr size_t length() const noexcept {
return 0;
}
constexpr symb_type* place(symb_type* p) const noexcept {
return p;
}
};
/*!
* @brief Пустое строковое выражение типа char
* @ingroup StrExprs
*/
inline constexpr empty_expr<u8s> eea{};
/*!
* @brief Пустое строковое выражение типа wchar_t
* @ingroup StrExprs
*/
inline constexpr empty_expr<uws> eew{};
/*!
* @brief Пустое строковое выражение типа char16_t
* @ingroup StrExprs
*/
inline constexpr empty_expr<u16s> eeu{};
/*!
* @brief Пустое строковое выражение типа char32_t
* @ingroup StrExprs
*/
inline constexpr empty_expr<u32s> eeuu{};
template<typename K>
struct expr_char {
using symb_type = K;
K value;
expr_char(K v) : value(v){}
constexpr size_t length() const noexcept {
return 1;
}
constexpr symb_type* place(symb_type* p) const noexcept {
*p++ = value;
return p;
}
};
/*!
* @brief Оператор сложения строкового выражения и одного символа
* @ingroup StrExprs
* @return строковое выражение, объединяющее переданное выражение и символ
* @details Пример:
* ```cpp
* reply = prompt + '>' + result;
* ```
*/
template<typename K, StrExprForType<K> A>
constexpr inline auto operator+(const A& a, K s) {
return strexprjoin_c<A, expr_char<K>>{a, s};
}
/*!
* @brief Генерирует строку из 1 заданного символа
* @ingroup StrExprs
* @param S - символ
* @return строковое выражение для строки из одного символа
*/
template<typename K>
constexpr inline auto e_char(K s) {
return expr_char<K>{s};
}
template<typename K, size_t N>
struct expr_literal {
using symb_type = K;
const K (&str)[N + 1];
constexpr size_t length() const noexcept {
return N;
}
constexpr symb_type* place(symb_type* p) const noexcept {
if constexpr (N != 0)
std::char_traits<K>::copy(p, str, N);
return p + N;
}
};
/*!
* @brief Преобразует строковый литерал в строковое выражение.
* @ingroup StrExprs
* @details Строковые литералы сами по себе не являются строковыми выражениями.
* Обычно в операциях конкатенации это не вызывает проблем, так как второй операнд уже является строковым выражением,
* и для него срабатывает сложение с литералом. Но есть ситуации, когда второй операнд тоже не является
* строковым выражением. Например:
* ```cpp
* int intVar = calculate();
* ...
* res = "text" + intVar;
* ...
* res = intVar + "text";
* ```
* В этом случае можно преобразовать литерал в строковое выражение двумя способами:
* - дописать _ss: `"text"_ss`, что преобразует литерал в simple_str_nt: `res = "text"_ss + intVar`
* - применить e_t: `e_t("text")`, что преобразует литерал в expr_literal: `res = e_t("text") + intVar`
*
* Во втором способе компилятор может более агрессивно применить оптимизации, связанные с известным при компиляции
* размером литерала.
*
* Хотя строго говоря, в этих ситуации можно пользоваться и другими способами:
* - Добавить операнд - пустое строковое выражение: `result = eea + "text" + intVar`, `result = "text" + eea + intVar`
* - Преобразовать другой операнд в строковое выражение: `result = "text" + e_num<u8s>(intVar)`.
*
* Все эти способы работают и выдают одинаковый результат. Каким пользоваться - дело вкуса.
*/
template<typename T, size_t N = const_lit<T>::Count>
constexpr inline auto e_t(T&& s) {
return expr_literal<typename const_lit<T>::symb_type, static_cast<size_t>(N - 1)>{s};
}
template<bool first, typename K, size_t N, typename A>
struct expr_literal_join {
using symb_type = K;
const K (&str)[N + 1];
const A& a;
constexpr size_t length() const noexcept {
return N + a.length();
}
constexpr symb_type* place(symb_type* p) const noexcept {
if constexpr (N != 0) {
if constexpr (first) {
std::char_traits<K>::copy(p, str, N);
return a.place(p + N);
} else {
p = a.place(p);
std::char_traits<K>::copy(p, str, N);
return p + N;
}
} else {
return a.place(p);
}
}
constexpr symb_type* len_and_place(symb_type* p) const noexcept {
a.length();
return place(p);
}
};
/*!
* @brief Оператор сложения для строкового выражения и строкового литерала такого же типа символов
* @ingroup StrExprs
* @return Строковое выражение, объединяющее операнды
*/
template<StrExpr A, typename K = typename A::symb_type, typename T, size_t N = const_lit_for<K, T>::Count>
constexpr inline auto operator+(const A& a, T&& s) {
return expr_literal_join<false, K, (N - 1), A>{s, a};
}
/*!
* @brief Оператор сложения для строкового литерала такого же типа символов и строкового выражения
* @ingroup StrExprs
* @return Строковое выражение, объединяющее операнды
*/
template<StrExpr A, typename K = typename A::symb_type, typename T, size_t N = const_lit_for<K, T>::Count>
constexpr inline auto operator+(T&& s, const A& a) {
return expr_literal_join<true, K, (N - 1), A>{s, a};
}
/*!
* @brief Тип строкового выражения, возвращающего N заданных символов.
* @ingroup StrExprs
* @details Количество символов и сам символ константы, т.е. задаются при компиляции.
* @tparam K - тип символа
* @tparam N - количество символов
* @tparam S - символ, по умолчанию пробел
*/
template<typename K, size_t N, size_t S = ' '>
struct expr_spaces {
using symb_type = K;
constexpr size_t length() const noexcept {
return N;
}
constexpr symb_type* place(symb_type* p) const noexcept {
if constexpr (N != 0)
std::char_traits<K>::assign(p, N, static_cast<K>(S));
return p + N;
}
};
/*!
* @brief Генерирует строку из N char пробелов
* @ingroup StrExprs
* @tparam N - Количество пробелов
* @return строковое выражение для N char пробелов
* @details Пример:
* ```cpp
* stringa text = e_spca<10>() + text + e_spca<10>();
* ```
*/
template<size_t N>
constexpr inline auto e_spca() {
return expr_spaces<u8s, N>();
}
/*!
* @brief Генерирует строку из N wchar_t пробелов
* @ingroup StrExprs
* @tparam N - Количество пробелов
* @return строковое выражение для N wchar_t пробелов
* @details Пример:
* ```cpp
* stringw text = e_spcw<10>() + text + e_spcw<10>();
* ```
*/
template<size_t N>
constexpr inline auto e_spcw() {
return expr_spaces<uws, N>();
}
/*!
* @brief Тип строкового выражения, возвращающего N заданных символов.
* @ingroup StrExprs
* @tparam K - тип символа
* @details Количество символов и сам символ переменные, т.е. могут меняться в рантайм.
* Напрямую обычно не используется, создается через e_c()
*/
template<typename K>
struct expr_pad {
using symb_type = K;
size_t len;
K s;
constexpr size_t length() const noexcept {
return len;
}
constexpr symb_type* place(symb_type* p) const noexcept {
if (len)
std::char_traits<K>::assign(p, len, s);
return p + len;
}
};
/*!
* @brief Генерирует строку из l символов s типа K
* @ingroup StrExprs
* @tparam K - тип символа
* @param l - количество символов
* @param s - символ
* @return строковое выражение, генерирующее строку из l символов k
*/
template<typename K>
constexpr inline auto e_c(size_t l, K s) {
return expr_pad<K>{ l, s };
}
/*!
* @brief Строковое выражение условного выбора
* @ingroup StrExprs
* @tparam A Тип ветки для true
* @tparam B Тип ветки для false
* @details Выражение, в зависимости от истинности условия генерирующее либо выражение A, либо выражение B.
* Напрямую тип обычно не используется, создаётся через e_choice()
*/
template<StrExpr A, StrExprForType<typename A::symb_type> B>
struct expr_choice {
using symb_type = typename A::symb_type;
using my_type = expr_choice<A, B>;
const A& a;
const B& b;
bool choice;
constexpr size_t length() const noexcept {
return choice ? a.length() : b.length();
}
constexpr symb_type* place(symb_type* ptr) const noexcept {
return choice ? a.place(ptr) : b.place(ptr);
}
};
/*!
* @brief Строковое выражение условного выбора
* @ingroup StrExprs
* @tparam A Тип ветки для true
* @details Выражение, в зависимости от истинности условия генерирующее либо выражение A, либо пустую строку.
* Напрямую тип обычно не используется, создаётся через e_if()
*/
template<StrExpr A>
struct expr_if {
using symb_type = typename A::symb_type;
using my_type = expr_if<A>;
const A& a;
bool choice;
constexpr size_t length() const noexcept {
return choice ? a.length() : 0;
}
constexpr symb_type* place(symb_type* ptr) const noexcept {
return choice ? a.place(ptr) : ptr;
}
};
/*!
* @brief Строковое выражение условного выбора
* @ingroup StrExprs
* @tparam A Тип ветки для true
* @details Выражение, в зависимости от истинности условия генерирующее либо выражение A, либо строку из строкового литерала.
* Напрямую тип обычно не используется, создаётся через e_choice()
*
* Так как строковые литералы не являются строковыми выражениями, то использовать их в виде одиночного выражения в частях
* e_choice или e_if требовало бы их обрамления какими-либо конструкциями, преобразующими их в строковое выражение.
* Приходилось бы писать например так:
* ```cpp
* e_choice(condition, text, e_t("empty"));
* e_choice(condition, text, eea + "empty");
* e_choice(condition, text, "empty"_ss);
* e_if(!condition, "empty"_ss);
* ```
* Это, с одной стороны - захламляет код, с другой - делает его менее оптимальным.
* Поэтому для таких случаев сделаны перегрузки e_choice и e_if для случаев, когда их параметрами являются строковые литералы.
* В этих перегрузках и используются expr_choice_one_lit и expr_choice_two_lit, позволяя писать так:
* ```cpp
* e_choice(condition, text, "empty");
* e_choice(condition, "false", "true");
* e_if(!condition, "empty");
* ```
*/
template<StrExpr A, size_t N, bool Compare>
struct expr_choice_one_lit {
using symb_type = typename A::symb_type;
const symb_type (&str)[N + 1];
const A& a;
bool choice;
constexpr size_t length() const noexcept {
return choice == Compare ? a.length() : N;
}
constexpr symb_type* place(symb_type* ptr) const noexcept {
if (choice == Compare) {
return a.place(ptr);
}
if constexpr (N != 0) {
std::char_traits<symb_type>::copy(ptr, str, N);
}
return ptr + N;
}
};
/*!
* @brief Строковое выражение условного выбора
* @ingroup StrExprs
* @details Выражение, в зависимости от истинности условия генерирующее либо один строковый литерал, либо другой.
* Напрямую тип обычно не используется, создаётся через e_choice()
*
* Так как строковые литералы не являются строковыми выражениями, то использовать их в виде одиночного выражения в частях
* e_choice или e_if требовало бы их обрамления какими-либо конструкциями, преобразующими их в строковое выражение.
* Приходилось бы писать например так:
* ```cpp
* e_choice(condition, text, e_t("empty"));
* e_choice(condition, text, eea + "empty");
* e_choice(condition, text, "empty"_ss);
* e_if(!condition, "empty"_ss);
* ```
* Это, с одной стороны - захламляет код, с другой - делает его менее оптимальным.
* Поэтому для таких случаев сделаны перегрузки e_choice и e_if для случаев, когда их параметрами являются строковые литералы.
* В этих перегрузках и используются expr_choice_one_lit и expr_choice_two_lit, позволяя писать так:
* ```cpp
* e_choice(condition, text, "empty");
* e_choice(condition, "false", "true");
* e_if(!condition, "empty");
* ```
*/
template<typename K, size_t N, size_t M>
struct expr_choice_two_lit {
using symb_type = K;
const symb_type (&str_a)[N + 1];
const symb_type (&str_b)[M + 1];
bool choice;
constexpr size_t length() const noexcept {
return choice ? N : M;
}
constexpr symb_type* place(symb_type* ptr) const noexcept {
if (choice) {
if constexpr (N != 0) {
std::char_traits<symb_type>::copy(ptr, str_a, N);
}
return ptr + N;
}
if constexpr (M != 0) {
std::char_traits<symb_type>::copy(ptr, str_b, M);
}
return ptr + M;
}
};
/*!
* @brief Создание условного строкового выражения expr_choice
* @ingroup StrExprs
* @tparam A - Тип выражение при истинности условия, выводится из аргумента
* @tparam B - Тип выражения при ложности условия, выводится из аргумента
* @param c - булево условие
* @param a - строковое выражение, выполняющееся при `c == true`
* @param b - строковое выражение, выполняющееся при `c == false`
* @details Служит для возможности в одном выражении выбирать разные варианты в зависимости от условия.
*
* Примеры:
* ```cpp
* columns_metadata.emplace_back(e_choice(name.is_empty(), "?column?", name) + "::" + metadata_column.type.to_string());
* ```
* ```cpp
* lstringa<512> str = e_choice(!ret_type_resolver_, sql_value::type_name(ret_type_), "any") + " " + name_ + "(";
* ```
* Иначе такие операции приходилось бы разбивать на несколько модификаций строки или применению временных строк,
* что не оптимально и снизит производительность. (Это проверяется в бенчмарке "Build Full Func Name")
*/
template<StrExpr A, StrExprForType<typename A::symb_type> B>
inline constexpr auto e_choice(bool c, const A& a, const B& b) {
return expr_choice<A, B>{a, b, c};
}
/*!
* @brief Перегрузка e_choice, когда третий аргумент - строковый литерал
* @ingroup StrExprs
*/
template<StrExpr A, typename T, size_t N = const_lit_for<typename A::symb_type, T>::Count>
inline constexpr auto e_choice(bool c, const A& a, T&& str) {
return expr_choice_one_lit<A, N - 1, true>{str, a, c};
}
/*!
* @brief Перегрузка e_choice, когда второй аргумент - строковый литерал
* @ingroup StrExprs
*/
template<StrExpr A, typename T, size_t N = const_lit_for<typename A::symb_type, T>::Count>
inline constexpr auto e_choice(bool c, T&& str, const A& a) {
return expr_choice_one_lit<A, N - 1, false>{str, a, c};
}
/*!
* @brief Перегрузка e_choice, когда второй и третий аргумент - строковые литералы
* @ingroup StrExprs
*/
template<typename T, typename L, size_t N = const_lit<T>::Count, size_t M = const_lit_for<typename const_lit<T>::symb_type, L>::Count>
inline constexpr auto e_choice(bool c, T&& str_a, L&& str_b) {
return expr_choice_two_lit<typename const_lit<T>::symb_type, N -1, M - 1>{str_a, str_b, c};
}
/*!
* @brief Создание условного строкового выражения expr_if
* @ingroup StrExprs
* @tparam A - Тип выражение при истинности условия, выводится из аргумента
* @param c - булево условие
* @param a - строковое выражение, выполняющееся при `c == true`
* @details Служит для возможности в одном выражении генерировать в зависимости от условия либо указанный вариант, либо пустую строку.
*
* Примеры:
* ```cpp
* void sql_func_info::build_full_name() {
* // Временный буфер для результата, возьмём с запасом
* lstringa<512> str = e_choice(!ret_type_resolver_, sql_value::type_name(ret_type_), "any") + " " + name_ + "(";
*
* bool add_comma = false;
*
* for (const auto& param : params_) {
* str += e_if(add_comma, ", ") + e_if(param.optional_, "[");
* param.allowed_types.to_string(str); // Добавляет к str названия допустимых типов
* if (param.optional_) {
* str += "]";
* }
* add_comma = true;
* }
* // Сохраним в stringa
* full_name_ = str + e_if(unlim_params_, e_if(add_comma, ", ") + "...") + ")";
* }
* ```
* Иначе такие операции приходилось бы разбивать на несколько модификаций строки или применению временных строк,
* что не оптимально и снизит производительность. (Этот пример проверяется в бенчмарке "Build Full Func Name")
*/
template<StrExpr A>
inline constexpr auto e_if(bool c, const A& a) {
return expr_if<A>{a, c};
}
/*!
* @brief Перегрузка e_if, когда второй аргумент - строковый литерал
* @ingroup StrExprs
*/
template<typename T, size_t N = const_lit<T>::Count>
inline constexpr auto e_if(bool c, T&& str) {
const typename const_lit<T>::symb_type empty[1] = {0};
return expr_choice_two_lit<typename const_lit<T>::symb_type, N - 1, 0>{str, empty, c};
}
/*!
* @brief Тип для использования std::string и std::string_view как источников в строковых выражениях
* @ingroup StrExprs
* @tparam K - тип символа
* @tparam T - тип источника
*/
template<typename K, typename T>
struct expr_stdstr {
using symb_type = K;
const T& t_;
expr_stdstr(const T& t) : t_(t){}
constexpr size_t length() const noexcept {
return t_.size();
}
constexpr symb_type* place(symb_type* p) const noexcept {
size_t s = t_.size();
std::char_traits<K>::copy(p, (const K*)t_.data(), s);
return p + s;
}
};
/*!
* @brief Оператор сложения для char строкового выражения и std::string
* @ingroup StrExprs
*/
template<StrExprForType<u8s> A>
auto operator+(const A& a, const std::string& s) {
return strexprjoin_c<A, expr_stdstr<u8s, std::string>, true>{a, s};
}
/*!
* @brief Оператор сложения для std::string и char строкового выражения
* @ingroup StrExprs
*/
template<StrExprForType<u8s> A>
auto operator+(const std::string& s, const A& a) {
return strexprjoin_c<A, expr_stdstr<u8s, std::string>, false>{a, s};
}
/*!
* @brief Оператор сложения для char строкового выражения и std::string_view
* @ingroup StrExprs
*/
template<StrExprForType<u8s> A>
auto operator+(const A& a, const std::string_view& s) {
return strexprjoin_c<A, expr_stdstr<u8s, std::string_view>, true>{a, s};
}
/*!
* @brief Оператор сложения для std::string_view и char строкового выражения
* @ingroup StrExprs
*/
template<StrExprForType<u8s> A>
auto operator+(const std::string_view& s, const A& a) {
return strexprjoin_c<A, expr_stdstr<u8s, std::string_view>, false>{a, s};
}
/*!
* @brief Оператор сложения для wchar_t строкового выражения и std::wstring
* @ingroup StrExprs
*/
template<StrExprForType<uws> A>
auto operator+(const A& a, const std::wstring& s) {
return strexprjoin_c<A, expr_stdstr<uws, std::wstring>, true>{a, s};
}
/*!
* @brief Оператор сложения для std::wstring и wchar_t строкового выражения
* @ingroup StrExprs
*/
template<StrExprForType<uws> A>
auto operator+(const std::wstring& s, const A& a) {
return strexprjoin_c<A, expr_stdstr<uws, std::wstring>, false>{a, s};
}
/*!
* @brief Оператор сложения для wchar_t строкового выражения и std::wstring_view
* @ingroup StrExprs
*/
template<StrExprForType<uws> A>
auto operator+(const A& a, const std::wstring_view& s) {
return strexprjoin_c<A, expr_stdstr<uws, std::wstring_view>, true>{a, s};
}
/*!
* @brief Оператор сложения для std::wstring_view и wchar_t строкового выражения
* @ingroup StrExprs
*/
template<StrExprForType<uws> A>
auto operator+(const std::wstring_view& s, const A& a) {
return strexprjoin_c<A, expr_stdstr<uws, std::wstring_view>, false>{a, s};
}
/*!
* @brief Оператор сложения для совместимого с wchar_t строкового выражения (char16_t или
* char32_t, в зависимости от компилятора) и std::wstring
* @ingroup StrExprs
*/
template<StrExprForType<wchar_type> A>
auto operator+(const A& a, const std::wstring& s) {
return strexprjoin_c<A, expr_stdstr<wchar_type, std::wstring>, true>{a, s};
}
/*!
* @brief Оператор сложения для std::wstring и совместимого с wchar_t строкового выражения
* (char16_t или char32_t, в зависимости от компилятора)
* @ingroup StrExprs
*/
template<StrExprForType<wchar_type> A>
auto operator+(const std::wstring& s, const A& a) {
return strexprjoin_c<A, expr_stdstr<wchar_type, std::wstring>, false>{a, s};
}
/*!
* @brief Оператор сложения для совместимого с wchar_t строкового выражения (char16_t или
* char32_t, в зависимости от компилятора) и std::wstring_view
* @ingroup StrExprs
*/
template<StrExprForType<wchar_type> A>
auto operator+(const A& a, const std::wstring_view& s) {
return strexprjoin_c<A, expr_stdstr<wchar_type, std::wstring_view>, true>{a, s};
}
/*!
* @brief Оператор сложения для std::wstring_view и совместимого с wchar_t строкового выражения
* (char16_t или char32_t, в зависимости от компилятора)
* @ingroup StrExprs
*/
template<StrExprForType<wchar_type> A>
auto operator+(const std::wstring_view& s, const A& a) {
return strexprjoin_c<A, expr_stdstr<wchar_type, std::wstring_view>, false>{a, s};
}
}// namespace simstr

89
readme.md Normal file
View File

@ -0,0 +1,89 @@
# simstr - библиотека строковых объектов и функций
Версия 1.0.
В этой библиотеке содержится реализация нескольких видов строковых объектов и различных алгоритмов для работы со строками.
Цель библиотеки - сделать работу со строками в С++ такой же простой и лёгкой, как во множестве других языков, особенно
скриптовых, но при этом сохранив оптимальность и производительность на уровне С и C++, и даже улучшив их.
Не секрет, что работа со строками в С++ зачастую доставляет боль. Класс `std::string` часто неудобен либо неэффективен.
Многих функций, обычно необходимых при работе со строками, просто нет, и их каждому приходится писать самому.
Эта библиотека не делалась как универсальный комбайн, который "может всё", я реализовывал то, что мне приходилось
использовать в работе, стараясь сделать это наиболее эффективным способом, и скромно надеюсь, что кое-что у меня получилось
и пригодится другим людям, либо напрямую, либо как источник идей.
Библиотека не претендует на роль "поменял хедер и всё заработало лучше". Многие методы я старался делать совместимыми
с `std::string` и `std::string_view`, но особо с этим не заморачивался. Переписывание старого кода на работу с simstr
потребует некоторых усилий, но уверяю, что они окупятся. А новый код писать с её применением легко и доставляет удовольствие :)
Основное отличие simstr от std::string - для работы со строками используется не единый универсальный класс, а несколько
видов объектов, каждый из которых хорош для своих целей, и при этом хорошо взаимодействующих друг с другом.
Если вы активно использовали std::string_view и понимали, в чём его преимущество и недостатки по сравнению с std::string,
то подход simstr вам также будет понятен.
## Основные возможности библиотеки
- Строки `char`, `char16_t`, `char32_t`, `wchar_t`.
- Прозрачное преобразование строк из одного типа символов в другой, с автоматической конвертацией между UTF-8, UTF-16, UTF-32,
используя [simdutf](https://github.com/simdutf/simdutf).
- Расширяемая система "Строковых выражений". Позволяет эффективно реализовать преобразование и сложение (конкатенацию) строк, литералов,
чисел и возможно других объектов.
- Строковые функции:
- Получение подстрок.
- Поиск подстрок и символов - с начала или с конца строки.
- Различный тримминг строк - справа, слева, везде, по пробельным символам, по заданным символам.
- Замена подстрок.
- Замена набора символов на набор соответствующих подстрок.
- Слияние (join) контейнеров строк в единую строку, с заданием разделителей и опций - "пропускать пустые", "разделитель после последней".
- Разбиение (split) строк на части по заданному разделителю. Разбиение возможно сразу в контейнер со строками, либо вызовом функтора для
каждой подстроки, либо путем итерации с помощью итератора `Splitter`.
- Интеграция с функциями форматирования `format` и `sprintf` (с автоматическим увеличением буфера).
Форматирование возможно для строк `char`, `wchar_t` и строк, совместимых с `wchar_t` по размеру.
То есть под Windows это `char16_t`, под Linux - `char32_t`. Писать свою библиотеку форматирования не входило в мои замыслы.
- Парсинг целых чисел с возможностью "тонкой" настройки при компиляции - можно задавать опции проверки переполнения,
пропуск пробельных символов, конкретное основание счисления либо автовыбор по префиксам `0x`, `0`, `0b`, `0o`,
допустимость знака `+`. Парсинг реализован для всех видов строк и символов.
- Парсинг double пока реализован вызовом стандартной библиотеки и работает только для строк `char`, `wchar_t` и совместимых с
`wchar_t` по размеру типов.
- Содержится минимальная поддержка Unicode при преобразовании `upper`, `lower` и регистро-независимом сравнении строк.
Работает только для символов первой плоскости Unicode (до 0xFFFF), а при смене регистра не учитываются случаи, когда один code point
может преобразовываться в несколько.
- Реализован `hash map` для ключей строкового типа, на базе `std::unordered_map`, с возможностью более эффективного хранения и
сравнения ключей по сравнению с ключами `std::string`. Поддерживается возможность регистро-независимого сравнения ключей (Ascii или
минимальный Unicode (см. предыдущий пункт)).
## Основные объекты библиотеки
- simple_str&lt;K> - самая простая строка (или кусок строки), иммутабельная, не владеющая, аналог `std::string_view`.
- simple_str_nt&lt;K> - то же самое, только заявляет, что заканчивается 0. Для работы со сторонними C-API.
- sstring&lt;K> - shared string, иммутабельная, владеющая, с разделяемым буфером символов, поддержка SSO.
- lstring&lt;K, N> - local string, мутабельная, владеющая, с задаваемым размером SSO буфера.
## Небольшой обзор и введение
[Читать здесь](docs/overview.md)
## Использование
`simstr` состоит из трёх заголовочных файлов и двух исходников. Можно подключать как CMake проект через `add_subdirectory` (библиотека `simstr`),
можно просто включить файлы в свой проект. Для сборки также требуется [simdutf](https://github.com/simdutf/simdutf), (уже подключена к репозитарию
как `git submodule`).
Для работы `simstr` требуется компилятор стандарта не ниже С++20 - используются концепты и std::format.
Работа проверялась под Windows на MSVC-19 и Clang-19, под Linux - на GCC-13 и Clang-21.
Также проверялась работа в WASM, сборка в Emscripten 4.0.6, Clang-21.
## Бенчмарки
Бенчмарки производятся с использованием фреймворка [Google benchmark](https://github.com/google/benchmark).
Постарался сделать замеры для наиболее типичных операций, встречающихся в обычной работе. Я проводил замеры на своём оборудовании, под
Windows и Linux (в WSL), с использованием компиляторов MSVC, Clang, GCC. Сторонние результаты приветствуются.
Также проводил замеры в WASM, сборка в Emscripten. Обращаю внимание, что под WASM в Emscripten собирается 32-битная сборка, а значит,
размеры буферов SSO в объектах меньше.
- [Исходный код бенчмарков](bench/bench_str.cpp)
- [Результаты бенчмарков](https://snegopat.ru/simstr/results.html)
## Примеры использования
Пока отдельных примеров использования не подготовлено, можно посмотреть тексты [тестов](tests/test_str.cpp),
[бенчмарков](bench/bench_str.cpp), и [утилиты подготовки html](bench/process_result.cpp) из результатов бенчмарков.
## Сгенерированная документация
[Находится здесь](https://snegopat.ru/simstr/docs/)

3018
src/simple_unicode.cpp Normal file

File diff suppressed because it is too large Load Diff

548
src/sstring.cpp Normal file
View File

@ -0,0 +1,548 @@
/*
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
* ver. 1.0
* Реализация строковых функций
*/
#include "simstr/simple_unicode.h"
#include "simstr/sstring.h"
#include <simdutf.h>
namespace simstr {
template class sstring<u8s>;
template class sstring<uws>;
template class sstring<u16s>;
template class sstring<u32s>;
// from sqlite.c
/*
** Notes On Invalid UTF-8:
**
** * This routine never allows a 7-bit character (0x00 through 0x7f) to
** be encoded as a multi-byte character. Any multi-byte character that
** attempts to encode a value between 0x00 and 0x7f is rendered as 0xfffd.
**
** * This routine never allows a UTF16 surrogate value to be encoded.
** If a multi-byte character attempts to encode a value between
** 0xd800 and 0xe000 then it is rendered as 0xfffd.
**
** * Bytes in the range of 0x80 through 0xbf which occur as the first
** byte of a character are interpreted as single-byte characters
** and rendered as themselves even though they are technically
** invalid characters.
**
** * This routine accepts over-length UTF8 encodings
** for unicode values 0x80 and greater. It does not change over-length
** encodings to 0xfffd as some systems recommend.
*/
static const uu8s sqlite3Utf8Trans1[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
};
u32s readUtf8Symbol(const uu8s*& ptr, const uu8s* end) {
u32s us = static_cast<u32s>(*ptr++);
if (us >= 0xC0) {
us = sqlite3Utf8Trans1[us - 0xC0];
while (ptr < end && (*ptr & 0xC0) == 0x80)
us = (us << 6) + (0x3F & *(ptr++));
if (us < 0x80 || (us & 0xFFFFF800) == 0xD800 || (us & 0xFFFFFFFE) == 0xFFFE) {
us = 0xFFFD;
}
}
return us;
}
void writeUtf8Symbol(uu8s*& write, u32s us) {
using u8 = uu8s;
if (us <= 0x80)
*write++ = (u8)us;
else if (us < 0x00800) {
*write++ = 0xC0 + (u8)((us >> 6) & 0x1F);
*write++ = 0x80 + (u8)(us & 0x3F);
} else if (us < 0x10000) {
*write++ = 0xE0 + (u8)((us >> 12) & 0x0F);
*write++ = 0x80 + (u8)((us >> 6) & 0x3F);
*write++ = 0x80 + (u8)(us & 0x3F);
} else {
*write++ = 0xF0 + (u8)((us >> 18) & 0x07);
*write++ = 0x80 + (u8)((us >> 12) & 0x3F);
*write++ = 0x80 + (u8)((us >> 6) & 0x3F);
*write++ = 0x80 + (u8)(us & 0x3F);
}
}
u32s readUtf16Symbol(const u16s*& ptr, const u16s* end) {
u32s us = static_cast<u32s>(*ptr++);
if (us >= 0xD800) {
if (us < 0xDC00 && ptr < end) {
if (u32s s = static_cast<u32s>(*ptr++); s >= 0xDC00 && s < 0xE000) {
return ((us & 0x3ff) << 10) + (s & 0x3ff) + 0x10000;
}
}
return 0xFFFD;
}
return us;
}
void writeUtf16Symbol(u16s*& ptr, u32s s) {
if (s < 0x10000) {
*ptr++ = static_cast<u16s>(s);
} else {
s -= 0x10000;
*ptr++ = 0xD800 + ((s >> 10) & 0x3FF);
*ptr++ = 0xDC00 + (s & 0x3FF);
}
}
size_t utf8len(u32s us) {
if (us <= 0x80)
return 1;
else if (us < 0x00800)
return 2;
else if (us < 0x10000)
return 3;
else
return 4;
}
SIMSTR_API size_t utf_convert_selector<u8s, u16s>::need_len(const u8s*src, size_t srcLen) {
return simdutf::utf16_length_from_utf8(src, srcLen);
}
SIMSTR_API size_t utf_convert_selector<u8s, u16s>::convert(const u8s* src, size_t srcLen, u16s* dest) {
return simdutf::convert_utf8_to_utf16(src, srcLen, dest);
}
SIMSTR_API size_t utf_convert_selector<u8s, u32s>::need_len(const u8s*src, size_t srcLen) {
return simdutf::utf32_length_from_utf8(src, srcLen);
}
SIMSTR_API size_t utf_convert_selector<u8s, u32s>::convert(const u8s* src, size_t srcLen, u32s* dest) {
return simdutf::convert_utf8_to_utf32(src, srcLen, dest);
}
SIMSTR_API size_t utf_convert_selector<u16s, u8s>::need_len(const u16s*src, size_t srcLen) {
return simdutf::utf8_length_from_utf16(src, srcLen);
}
SIMSTR_API size_t utf_convert_selector<u16s, u8s>::convert(const u16s* src, size_t srcLen, u8s* dest) {
return simdutf::convert_utf16_to_utf8(src, srcLen, dest);
}
SIMSTR_API size_t utf_convert_selector<u16s, u32s>::need_len(const u16s*src, size_t srcLen) {
return simdutf::utf32_length_from_utf16(src, srcLen);
}
SIMSTR_API size_t utf_convert_selector<u16s, u32s>::convert(const u16s* src, size_t srcLen, u32s* dest) {
return simdutf::convert_utf16_to_utf32(src, srcLen, dest);
}
SIMSTR_API size_t utf_convert_selector<u32s, u8s>::need_len(const u32s*src, size_t srcLen) {
return simdutf::utf8_length_from_utf32(src, srcLen);
}
SIMSTR_API size_t utf_convert_selector<u32s, u8s>::convert(const u32s* src, size_t srcLen, u8s* dest) {
return simdutf::convert_utf32_to_utf8(src, srcLen, dest);
}
SIMSTR_API size_t utf_convert_selector<u32s, u16s>::need_len(const u32s*src, size_t srcLen) {
return simdutf::utf16_length_from_utf32(src, srcLen);
}
SIMSTR_API size_t utf_convert_selector<u32s, u16s>::convert(const u32s* src, size_t srcLen, u16s* dest) {
return simdutf::convert_utf32_to_utf16(src, srcLen, dest);
}
inline u32s makeLowerU(u32s s) {
if (isAsciiUpper(s))
return s | 0x20;
else if (s > 127 && s < 0x10000)
return simpleUnicodeLower(static_cast<uint16_t>(s));
else
return s;
}
inline u32s makeUpperU(u32s s) {
if (isAsciiLower(s))
return s & ~0x20;
else if (s > 127 && s < 0x10000)
return simpleUnicodeUpper(static_cast<uint16_t>(s));
else
return s;
}
inline u32s makeFoldU(u32s s) {
if (isAsciiUpper(s))
return s | 0x20;
else if (s > 127 && s < 0x10000)
return simpleUnicodeFold(static_cast<uint16_t>(s));
else
return s;
}
/*
* Поиск utf-8 symbols, которые меняют свою длину при upper/lower преобразовании
* вот они нашлись
* "İiıIſSȺⱥȾⱦɐⱯɑⱭɫⱢɱⱮɽⱤẞßΙΩωkÅåⱢɫⱤɽⱥȺⱦȾⱭɑⱮɱⱯɐ"
l2u ıIſSɐⱯɑⱭɫⱢɱⱮɽⱤΙⱥȺⱦȾ
u2l İiȺⱥȾⱦẞßΩωkÅåⱢɫⱤɽⱭɑⱮɱⱯɐ
void findStrange() {
u16s badsL2U[100], * pBadslu = badsL2U;
u16s badsU2L[100], * pBadsul = badsU2L;
uu8s buf[20];
size_t allToUpper = 0, allToLower = 0, lowerbadshorter = 0, upperbadshorter = 0, lowerbadlonger = 0, upperbadlonger = 0;
for (u32s s = 128; s <= 0xFFFF; s++) {
u16s upper = makeUpperU(s);
if (upper != s) {
allToUpper++;
uu8s* pTest = buf;
writeUtf8Symbol(pTest, s);
size_t len1 = pTest - buf;
pTest = buf;
writeUtf8Symbol(pTest, upper);
size_t len2 = pTest - buf;
if (len1 != len2) {
*pBadslu++ = s;
*pBadslu++ = upper;
if (len1 > len2) {
upperbadshorter++;
} else if (len1 < len2) {
upperbadlonger++;
}
}
}
u16s lower = makeLowerU(s);
if (lower != s) {
allToLower++;
uu8s* pTest = buf;
writeUtf8Symbol(pTest, s);
size_t len1 = pTest - buf;
pTest = buf;
writeUtf8Symbol(pTest, lower);
size_t len2 = pTest - buf;
if (len1 != len2) {
*pBadsul++ = s;
*pBadsul++ = lower;
if (len1 > len2) {
lowerbadshorter++;
} else if (len1 < len2) {
lowerbadlonger++;
}
}
}
}
*pBadsul = 0;
*pBadslu = 0;
return;
}
*/
template<auto Op>
size_t utf8_case_change(const u8s*& src, size_t len, u8s*& dest, size_t lenBuffer) {
// Допущение для оптимизации - считается, что выделенный буфер записи всегда не меньше длины буфера чтения
// и что буфер записи не начинается внутри буфера чтения
// то есть если символ считан, и длина записываемого символа не больше считанного, то он поместится в буфер записи
// и не перетрет символы, которые еще не прочитали
// По другому работать откажемся
if (lenBuffer < len || (dest > src && dest < src + len))
return len;
const uu8s *beginReadPos = reinterpret_cast<const uu8s*>(src), *readPos = beginReadPos, *endReadPos = beginReadPos + len,
*readFromPos = readPos;
uu8s *beginWritePos = reinterpret_cast<uu8s*>(dest), *writePos = beginWritePos, *endWritePos = writePos + lenBuffer, *tempWrite;
size_t state = 0, writedSymbolLen, needExtraLen = 0;
u32s readedSymbol, writedSymbol;
lstringa<4096> tempStore;
while (readPos < endReadPos) {
readedSymbol = readUtf8Symbol(readPos, endReadPos), writedSymbol = Op(readedSymbol);
writedSymbolLen = utf8len(writedSymbol);
switch (state) {
case 0: // начальное состояние
// Так как выделенный буфер записи всегда не меньше длины буфера чтения
// то если символ считан, и длина записываемого символа не больше считанного,
// то он поместится в буфер записи, можно не проверять
// оптимизация для inplace конвертации в идеальном случае
if (writePos == readFromPos && readedSymbol == writedSymbol) {
writePos = const_cast<uu8s*>(readPos);
readFromPos = readPos;
continue;
}
if (writePos + writedSymbolLen <= endWritePos && (writePos > readPos || writePos + writedSymbolLen <= readPos)) {
// всё отлично
writeUtf8Symbol(writePos, writedSymbol);
} else {
state = 1;
goto state1;
}
break;
case 1:
state1:
// До этого когда-то был считан символ, при записи ставший длиннее.
// Можно его писать, но надо проверять, что записываемый символ:
// - не перезатрёт читаемые
// - не выйдет за границы буфера записи
// - восстановит обычный режим, если записываемый символ короче прочитанного
if (writePos + writedSymbolLen > endWritePos) {
// Записываемый символ не поместится в буфер записи
// Запомним, где это произошло, подсчитаем символы далее
src = reinterpret_cast<const u8s*>(readFromPos);
dest = reinterpret_cast<u8s*>(writePos);
needExtraLen = 0;
state = 2;
goto state2;
} else if (writePos < readPos && writePos + writedSymbolLen > readPos) {
// Совсем плохой случай - записываемый символ перезатрет следующий читаемый
// Запомним, где это произошло, подсчитаем символы далее
src = reinterpret_cast<const u8s*>(readFromPos);
dest = reinterpret_cast<u8s*>(writePos);
needExtraLen = 0;
if (lenBuffer > len) {
// считаем, что это второй вызов, и места в буфере в итоге хватит
// поэтому будем сохранять считанные символы в свой буфер, а потом скопируем их в результат
tempWrite = reinterpret_cast<uu8s*>(tempStore.reserve(lenBuffer - static_cast<size_t>(writePos - beginWritePos)));
state = 3;
goto state3;
} else {
// Это первый вызов, будем просто считать нужное место
state = 2;
goto state2;
}
} else {
// Можем записать прочитанный символ
writeUtf8Symbol(writePos, writedSymbol);
// Возможно, мы выровнялись по прочитанным/записанным байтам, тогда можно снова писать в буфер
// в обычном состоянии
size_t allReaded = static_cast<size_t>(readPos - beginReadPos);
size_t allWrite = static_cast<size_t>(writePos - beginWritePos);
if (allReaded >= allWrite) {
// вернулись в обычное состояние
state = 0;
}
}
break;
case 2:
state2:
// Место в буфере кончилось, просто считаем нужное место
needExtraLen += writedSymbolLen;
break;
case 3:
state3:
// Был прочитан удлинившийся символ, который мог перезатереть читаемые.
// Конец буфера записи не достигнут, но писать туда нельзя.
// При этом известно, что место в буфере выделено
// с нужным запасом, и сейчас мы просто запоминаем считанные символы, чтобы
// потом вписать их когда позволит указатель чтения
if (writePos + writedSymbolLen <= readPos || readPos == endReadPos) {
// Опа, символ стал короче и снова влезает в буфер. Или все прочитали, можно записывать
std::char_traits<u8s>::copy(dest, tempStore.symbols(), needExtraLen);
writeUtf8Symbol(writePos, writedSymbol);
state = 0;
} else {
if (writePos + writedSymbolLen > endWritePos) {
// Таки всё-равно не влезем в буфер
state = 2;
goto state2;
}
writeUtf8Symbol(tempWrite, writedSymbol);
writePos += writedSymbolLen;
needExtraLen += writedSymbolLen;
}
break;
}
readFromPos = readPos;
}
if (state == 0 || state == 1) {
// все отлично, можно возвращать получившуюся длину
src = reinterpret_cast<const u8s*>(readFromPos);
dest = reinterpret_cast<u8s*>(writePos);
return static_cast<size_t>(writePos - beginWritePos);
} else {
size_t writedCount = static_cast<size_t>(dest - (u8s*)beginWritePos);
size_t needBuffer = writedCount + needExtraLen;
if (needBuffer <= lenBuffer) {
// значит попали во 2ое состояние и считали символы, так как перезатирали читаемые
// но видимо потом попались укоротившиеся и по итогу всё-равно все влезет, только
// нужно временно сохранять символы. Запустим еще раз
size_t readedCount = static_cast<size_t>((uu8s*)src - beginReadPos);
len -= readedCount;
lenBuffer -= writedCount; // по идее они должны быть одинаковые
utf8_case_change<Op>(src, len, dest, lenBuffer + 1);
}
// в dest и src уже сохранены последние позиции. Вернем нужную длину
return needBuffer;
}
}
SIMSTR_API size_t unicode_traits<u8s>::upper(const u8s*& src, size_t len, u8s*& dest, size_t lenBuffer) {
return utf8_case_change<makeUpperU>(src, len, dest, lenBuffer);
}
SIMSTR_API size_t unicode_traits<u8s>::lower(const u8s*& src, size_t len, u8s*& dest, size_t lenBuffer) {
return utf8_case_change<makeLowerU>(src, len, dest, lenBuffer);
}
template<auto Op>
void utf16_change_case(const u16s* src, size_t len, u16s* dest) {
if (dest != src) {
// не inplace - надо писать все символы
for (size_t l = 0; l < len; l++)
dest[l] = static_cast<u16s>(Op(src[l]));
} else {
// inplace - будем писать только измененные символы
for (size_t l = 0; l < len; l++) {
u16s s = src[l], s1 = static_cast<u16s>(Op(s));
if (s != s1)
dest[l] = s1;
}
}
}
void unicode_traits<u16s>::upper(const u16s* src, size_t len, u16s* dest) {
utf16_change_case<makeUpperU>(src, len, dest);
}
void unicode_traits<u16s>::lower(const u16s* src, size_t len, u16s* dest) {
utf16_change_case<makeLowerU>(src, len, dest);
}
template<auto Op>
void utf32_change_case(const u32s* src, size_t len, u32s* dest) {
if (dest != src) {
// не inplace - надо писать все символы
for (size_t l = 0; l < len; l++)
*dest++ = Op(*src++);
} else {
// inplace - будем писать только измененные символы
for (size_t l = 0; l < len; l++, src++, dest++) {
u32s s = *src, s1 = Op(s);
if (s != s1)
*dest = s1;
}
}
}
SIMSTR_API void unicode_traits<u32s>::upper(const u32s* src, size_t len, u32s* dest) {
utf32_change_case<makeUpperU>(src, len, dest);
}
SIMSTR_API void unicode_traits<u32s>::lower(const u32s* src, size_t len, u32s* dest) {
utf32_change_case<makeLowerU>(src, len, dest);
}
SIMSTR_API int unicode_traits<u8s>::compareiu(const u8s* text1, size_t len1, const u8s* text2, size_t len2) {
if (!len1) {
return len2 == 0 ? 0 : -1;
} else if (!len2)
return 1;
const uu8s *ptr1 = reinterpret_cast<const uu8s*>(text1), *ptr2 = reinterpret_cast<const uu8s*>(text2),
*ptr1End = ptr1 + len1, *ptr2End = ptr2 + len2;
for (;;) {
u32s s1 = makeFoldU(readUtf8Symbol(ptr1, ptr1End)), s2 = makeFoldU(readUtf8Symbol(ptr2, ptr2End));
if (s1 > s2)
return 1;
else if (s1 < s2)
return -1;
else if (ptr1 >= ptr1End)
return ptr2 >= ptr2End ? 0 : -1;
else if (ptr2 >= ptr2End)
return 1;
}
}
SIMSTR_API int unicode_traits<u16s>::compareiu(const u16s* text1, size_t len1, const u16s* text2, size_t len2) {
if (!len1) {
return len2 == 0 ? 0 : -1;
} else if (!len2)
return 1;
const u16s *ptr1End = text1 + len1, *ptr2End = text2 + len2;
for (;;) {
u32s s1 = makeFoldU(readUtf16Symbol(text1, ptr1End)), s2 = makeFoldU(readUtf16Symbol(text2, ptr2End));
if (s1 > s2)
return 1;
else if (s1 < s2)
return -1;
else if (text1 >= ptr1End)
return text2 >= ptr2End ? 0 : -1;
else if (text2 >= ptr2End)
return 1;
}
}
SIMSTR_API int unicode_traits<u32s>::compareiu(const u32s* text1, size_t len1, const u32s* text2, size_t len2) {
if (!len1) {
return len2 == 0 ? 0 : -1;
} else if (!len2)
return 1;
const u32s *ptr1End = text1 + len1, *ptr2End = text2 + len2;
for (;;) {
u32s s1 = makeFoldU(*text1++), s2 = makeFoldU(*text2++);
if (s1 > s2)
return 1;
else if (s1 < s2)
return -1;
else if (text1 > ptr1End)
return text2 >= ptr2End ? 0 : -1;
else if (text2 > ptr2End)
return 1;
}
}
SIMSTR_API size_t unicode_traits<u8s>::hashia(const u8s* src, size_t l) {
size_t h = fnv::basis;
for (size_t i = 0; i < l; i++) {
h = (h ^ (uu8s)makeAsciiLower(src[i])) * fnv::prime;
}
return h;
}
SIMSTR_API size_t unicode_traits<u8s>::hashiu(const u8s* src, size_t l) {
size_t h = fnv::basis;
const uu8s *ptr = (const uu8s*)src, *pEnd = ptr + l;
while (ptr < pEnd) {
h = (h ^ makeFoldU(readUtf8Symbol(ptr, pEnd))) * fnv::prime;
}
return h;
}
SIMSTR_API size_t unicode_traits<u16s>::hashia(const u16s* src, size_t l) {
size_t h = fnv::basis;
for (size_t i = 0; i < l; i++) {
h = (h ^ makeAsciiLower(src[i])) * fnv::prime;
}
return h;
}
SIMSTR_API size_t unicode_traits<u16s>::hashiu(const u16s* src, size_t l) {
size_t h = fnv::basis;
const u16s* pEnd = src + l;
while (src < pEnd) {
h = (h ^ makeFoldU(readUtf16Symbol(src, pEnd))) * fnv::prime;
}
return h;
}
SIMSTR_API size_t unicode_traits<u32s>::hashia(const u32s* src, size_t l) {
size_t h = fnv::basis;
for (size_t i = 0; i < l; i++) {
h = (h ^ makeAsciiLower(src[i])) * fnv::prime;
}
return h;
}
SIMSTR_API size_t unicode_traits<u32s>::hashiu(const u32s* src, size_t l) {
size_t h = fnv::basis;
for (size_t i = 0; i < l; i++) {
h = (h ^ makeFoldU(src[i])) * fnv::prime;
}
return h;
}
} // namespace simstr

11
tests/CMakeLists.txt Normal file
View File

@ -0,0 +1,11 @@
# CMakeList.txt : CMake project for core_as, include source and define
# project specific logic here.
#
add_executable(testStr test_str.cpp)
target_link_libraries(testStr simstr gtest_main)
add_test(NAME testStr COMMAND testStr)
if (EMSCRIPTEN)
set_target_properties (testStr PROPERTIES SUFFIX .html)
endif(EMSCRIPTEN)

1754
tests/test_str.cpp Normal file

File diff suppressed because it is too large Load Diff