2025-04-05 14:21:11 +00:00
/*
2026-07-24 13:24:40 +00:00
* ver . 1.8 .2
2025-04-05 14:21:11 +00:00
* ( c ) П р о е к т " SimStr " , А л е к с а н д р О р е ф к о в orefkov @ gmail . com
* Б е н ч м а р к и
2026-02-08 11:17:03 +00:00
* ( c ) Project " SimStr " , Aleksandr Orefkov orefkov @ gmail . com
* Benchmarks
2025-04-05 14:21:11 +00:00
*/
2026-02-14 10:09:54 +00:00
# include <stringzilla/stringzilla.h>
# include <stringzilla/stringzilla.hpp>
2025-04-05 14:21:11 +00:00
# include "bench.h"
# include <sstream>
# include <string>
2025-11-25 15:55:16 +00:00
# include <charconv>
2026-02-04 14:25:40 +00:00
# include <iomanip>
2026-02-08 11:17:03 +00:00
# include <fmt/format.h>
# include <fmt/compile.h>
2026-02-10 20:35:02 +00:00
using namespace simstr ;
using namespace std : : literals ;
2026-02-08 11:17:03 +00:00
# ifdef EMSCRIPTEN
# include <emscripten.h>
2026-02-12 16:47:32 +00:00
bool do_sync = false ;
2026-02-08 11:17:03 +00:00
static void DoTeardown ( const benchmark : : State & state ) {
2026-02-10 20:35:02 +00:00
// Это нужно чтобы интерфейс браузера обновился
// This is necessary for the browser interface to refresh.
2026-02-12 16:47:32 +00:00
if ( ! do_sync ) {
emscripten_sleep ( 1 ) ;
}
2026-02-08 11:17:03 +00:00
}
# undef BENCHMARK
# define BENCHMARK(...) \
BENCHMARK_PRIVATE_DECLARE ( _benchmark_ ) = \
( : : benchmark : : internal : : RegisterBenchmarkInternal ( \
: : benchmark : : internal : : make_unique < \
: : benchmark : : internal : : FunctionBenchmark > ( # __VA_ARGS__ , \
2026-02-10 20:35:02 +00:00
__VA_ARGS__ ) ) ) - > Teardown ( DoTeardown )
2025-04-05 14:21:11 +00:00
2026-02-10 20:35:02 +00:00
# undef BENCHMARK_CAPTURE
# define BENCHMARK_CAPTURE(func, test_case_name, ...) \
BENCHMARK_PRIVATE_DECLARE ( _benchmark_ ) = \
( : : benchmark : : internal : : RegisterBenchmarkInternal ( \
: : benchmark : : internal : : make_unique < \
: : benchmark : : internal : : FunctionBenchmark > ( \
# func " / " #test_case_name, \
[ ] ( : : benchmark : : State & st ) { func ( st , __VA_ARGS__ ) ; } ) ) ) - > Teardown ( DoTeardown )
# endif
2025-04-05 14:21:11 +00:00
# define TEST_TEXT "Test text"
# define LONG_TEXT "123456789012345678901234567890"
# define TEXT_16 "abbaabbaabbaabba"
2026-02-14 10:09:54 +00:00
//#define CHECK_RESULT
2025-04-05 14:21:11 +00:00
void __ ( benchmark : : State & state ) { for ( auto _ : state ) { } }
2026-02-14 10:09:54 +00:00
namespace sz = ashvardanian : : stringzilla ;
sz : : string email_concat_stringzilla_app ( sz : : string name , sz : : string_view domain , sz : : string_view tld ) {
return name . append ( " @ " ) . append ( domain ) . append ( " . " ) . append ( tld ) ;
}
//> sz::string email_concat_stringzilla_app(sz::string name, sz::string_view domain, sz::string_view tld) {
void ConcatEmailSzApp ( benchmark : : State & state ) {
sz : : string name = " username " ;
sz : : string_view domain = " verybigdomain " , tld = " tld " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( name ) ;
benchmark : : DoNotOptimize ( domain ) ;
benchmark : : DoNotOptimize ( tld ) ;
auto email = email_concat_stringzilla_app ( name , domain , tld ) ;
benchmark : : DoNotOptimize ( email ) ;
}
}
sz : : string email_concat_stringzilla_exp ( sz : : string name , sz : : string_view domain , sz : : string_view tld ) {
return sz : : string { name | sz : : string_view { " @ " } | domain | sz : : string_view { " . " } | tld } ;
}
//> sz::string email_concat_stringzilla_exp(sz::string name, sz::string_view domain, sz::string_view tld) {
void ConcatEmailSzExp ( benchmark : : State & state ) {
sz : : string name = " username " ;
sz : : string_view domain = " verybigdomain " , tld = " tld " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( name ) ;
benchmark : : DoNotOptimize ( domain ) ;
benchmark : : DoNotOptimize ( tld ) ;
auto email = email_concat_stringzilla_exp ( name , domain , tld ) ;
benchmark : : DoNotOptimize ( email ) ;
}
}
std : : string email_concat_format ( std : : string_view name , std : : string_view domain , std : : string_view tld ) {
return std : : format ( " {}@{}.{} " , name , domain , tld ) ;
}
//> std::string email_concat_format(std::string_view name, std::string_view domain, std::string_view tld) {
void ConcatEmailFormat ( benchmark : : State & state ) {
std : : string_view name = " username " , domain = " verybigdomain " , tld = " tld " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( name ) ;
benchmark : : DoNotOptimize ( domain ) ;
benchmark : : DoNotOptimize ( tld ) ;
auto email = email_concat_format ( name , domain , tld ) ;
benchmark : : DoNotOptimize ( email ) ;
}
}
std : : string email_concat_stream ( std : : string_view name , std : : string_view domain , std : : string_view tld ) {
std : : stringstream s ;
s < < name < < " @ " < < domain < < " . " < < tld ;
return s . str ( ) ;
}
//> std::string email_concat_stream(std::string_view name, std::string_view domain, std::string_view tld) {
void ConcatEmailStream ( benchmark : : State & state ) {
std : : string_view name = " username " , domain = " verybigdomain " , tld = " tld " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( name ) ;
benchmark : : DoNotOptimize ( domain ) ;
benchmark : : DoNotOptimize ( tld ) ;
auto email = email_concat_stream ( name , domain , tld ) ;
benchmark : : DoNotOptimize ( email ) ;
}
}
std : : string email_concat_std ( std : : string name , std : : string_view domain , std : : string_view tld ) {
return name . append ( " @ " ) . append ( domain ) . append ( " . " ) . append ( tld ) ;
}
//> std::string email_concat_std(std::string name, std::string_view domain, std::string_view tld) {
void ConcatEmailStd ( benchmark : : State & state ) {
std : : string name = " username " ;
std : : string_view domain = " verybigdomain " , tld = " tld " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( name ) ;
benchmark : : DoNotOptimize ( domain ) ;
benchmark : : DoNotOptimize ( tld ) ;
auto email = email_concat_std ( name , domain , tld ) ;
benchmark : : DoNotOptimize ( email ) ;
}
}
std : : string email_concat_std_expr ( std : : string_view name , std : : string_view domain , std : : string_view tld ) {
return + name + " @ " + domain + " . " + tld ;
}
//> std::string email_concat_std_expr(std::string_view name, std::string_view domain, std::string_view tld) {
void ConcatEmailStdExp ( benchmark : : State & state ) {
std : : string_view name = " username " , domain = " verybigdomain " , tld = " tld " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( name ) ;
benchmark : : DoNotOptimize ( domain ) ;
benchmark : : DoNotOptimize ( tld ) ;
auto email = email_concat_std_expr ( name , domain , tld ) ;
benchmark : : DoNotOptimize ( email ) ;
}
}
stringa email_concat_sim_expr ( ssa name , ssa domain , ssa tld ) {
return name + " @ " + domain + " . " + tld ;
}
//> stringa email_concat_sim_expr(ssa name, ssa domain, ssa tld) {
void ConcatEmailSimExp ( benchmark : : State & state ) {
ssa name = " username " , domain = " verybigdomain " , tld = " tld " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( name ) ;
benchmark : : DoNotOptimize ( domain ) ;
benchmark : : DoNotOptimize ( tld ) ;
auto email = email_concat_sim_expr ( name , domain , tld ) ;
benchmark : : DoNotOptimize ( email ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ----- Concatenate email --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( ConcatEmailFormat ) - > Name ( " Concat email std::format " ) ;
BENCHMARK ( ConcatEmailStream ) - > Name ( " Concat email std::stringstream " ) ;
BENCHMARK ( ConcatEmailSzApp ) - > Name ( " Concat email stringzilla append " ) ;
BENCHMARK ( ConcatEmailSzExp ) - > Name ( " Concat email stringzilla concat " ) ;
BENCHMARK ( ConcatEmailStd ) - > Name ( " Concat email std::string append " ) ;
BENCHMARK ( ConcatEmailStdExp ) - > Name ( " Concat email std::string by strexpr " ) ;
BENCHMARK ( ConcatEmailSimExp ) - > Name ( " Concat email stringa " ) ;
2025-04-05 14:21:11 +00:00
2026-01-21 11:59:17 +00:00
void ConcatStdToStd ( benchmark : : State & state ) {
std : : string s1 = " start " ;
for ( auto _ : state ) {
for ( int i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
std : : string str = s1 + std : : to_string ( i ) + " end " ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
void ConcatSimToStd ( benchmark : : State & state ) {
std : : string s1 = " start " ;
for ( auto _ : state ) {
for ( int i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
std : : string str = + s1 + i + " end " ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
void ConcatSimToSim ( benchmark : : State & state ) {
stra s1 = " start " ;
for ( auto _ : state ) {
for ( int i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
stringa str = s1 + i + " end " ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-01-29 14:56:15 +00:00
void ConcatSimToSimConcat ( benchmark : : State & state ) {
stra s1 = " start " ;
for ( auto _ : state ) {
for ( int i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
stringa str = e_concat ( " " , s1 , i , " end " ) ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-01-21 11:59:17 +00:00
BENCHMARK ( __ ) - > Name ( " ----- Concatenate string + Number + \" Literal \" --------- " ) - > Repetitions ( 1 ) ;
2026-01-29 14:56:15 +00:00
BENCHMARK ( ConcatStdToStd ) - > Name ( " Concat std::string and number by std to std::string " ) ;
BENCHMARK ( ConcatSimToStd ) - > Name ( " Concat std::string and number by StrExpr to std::string " ) ;
BENCHMARK ( ConcatSimToSim ) - > Name ( " Concat stringa and number by StrExpr to simstr::stringa " ) ;
BENCHMARK ( ConcatSimToSimConcat ) - > Name ( " Concat stringa and number by e_concat to simstr::stringa " ) ;
2026-01-21 11:59:17 +00:00
2026-01-30 14:30:09 +00:00
void ConcatStdToFmtHex ( benchmark : : State & state ) {
2026-01-21 11:59:17 +00:00
// We use a short string so that the longest result is 15 characters and fits in the std::string SSO buffer.
std : : string s1 = " art " ;
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
2026-01-30 14:30:09 +00:00
// It is not worked for char8_t, char16_t, char32_t :(
std : : string str = s1 + std : : format ( " {:#x} " , i ) + " end " ;
2026-01-21 11:59:17 +00:00
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-01-30 14:30:09 +00:00
void ConcatAllFmtToHex ( benchmark : : State & state ) {
// We use a short string so that the longest result is 15 characters and fits in the std::string SSO buffer.
std : : string s1 = " art " ;
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
// It is not worked for char8_t, char16_t, char32_t :(
std : : string str = std : : format ( " {}{:#x} end " , s1 , i ) ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
void ConcatStdToCharsHex ( benchmark : : State & state ) {
// We use a short string so that the longest result is 15 characters and fits in the std::string SSO buffer.
std : : string s1 = " art " ;
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
// it worked only for char :(
char buf [ 40 ] ;
size_t len = std : : to_chars ( buf , buf + std : : size ( buf ) , i , 16 ) . ptr - buf ;
std : : string str = s1 + " 0x " + std : : string ( buf , len ) + " end " ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-01-21 11:59:17 +00:00
void ConcatSimToStdHex ( benchmark : : State & state ) {
// We use a short string so that the longest result is 15 characters and fits in the std::string SSO buffer.
std : : string s1 = " art " ;
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
2026-01-30 14:30:09 +00:00
// Can work for all types of symbols
2026-02-08 11:17:03 +00:00
std : : string str = + s1 + i / 1 _f16 + " end " ;
2026-01-21 11:59:17 +00:00
benchmark : : DoNotOptimize ( str ) ;
}
}
}
void ConcatSimToSimHex ( benchmark : : State & state ) {
// stringa SSO buffer is 23, but we use a short string to compare under the same conditions
stra s1 = " art " ;
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
2026-01-30 14:30:09 +00:00
// Can work for all types of symbols
2026-02-08 11:17:03 +00:00
stringa str = s1 + i / 1 _f16 + " end " ;
2026-01-21 11:59:17 +00:00
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-01-29 14:56:15 +00:00
void ConcatSimToSimHexC ( benchmark : : State & state ) {
// stringa SSO buffer is 23, but we use a short string to compare under the same conditions
stra s1 = " art " ;
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
2026-01-30 14:30:09 +00:00
// Can work for all types of symbols
2026-02-08 11:17:03 +00:00
stringa str = e_concat ( " " , s1 , i / 1 _f16 , " end " ) ;
2026-01-29 14:56:15 +00:00
benchmark : : DoNotOptimize ( str ) ;
}
}
}
void ConcatSimToSimHexS ( benchmark : : State & state ) {
// stringa SSO buffer is 23, but we use a short string to compare under the same conditions
stra s1 = " art " ;
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
2026-02-08 11:17:03 +00:00
stringa str = e_subst ( " {}{} end " , s1 , i / 1 _f16 ) ;
2026-01-29 14:56:15 +00:00
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-01-31 14:24:12 +00:00
void ConcatSimToSimHexVS ( benchmark : : State & state ) {
// stringa SSO buffer is 23, but we use a short string to compare under the same conditions
stra s1 = " art " ;
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
2026-02-08 11:17:03 +00:00
stringa str = e_vsubst ( " {}{} end " _ss , s1 , i / 1 _f16 ) ;
2026-01-31 14:24:12 +00:00
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-01-21 11:59:17 +00:00
BENCHMARK ( __ ) - > Name ( " ----- Concatenate string + Hex Number + \" Literal \" --------- " ) - > Repetitions ( 1 ) ;
2026-01-30 14:30:09 +00:00
BENCHMARK ( ConcatStdToFmtHex ) - > Name ( " Concat std::string and format hex number and literal to std::string " ) ;
BENCHMARK ( ConcatAllFmtToHex ) - > Name ( " std::format std::string and hex number by literal to std::string " ) ;
2026-02-03 07:38:21 +00:00
BENCHMARK ( ConcatStdToCharsHex ) - > Name ( " Concat std::string and std::to_chars and string to std::string " ) ;
2026-01-30 14:30:09 +00:00
BENCHMARK ( ConcatSimToStdHex ) - > Name ( " Concat std::string and hex number and literal by StrExpr to std::string " ) ;
BENCHMARK ( ConcatSimToSimHex ) - > Name ( " Concat stringa and hex number and literal by StrExpr to simstr::stringa " ) ;
BENCHMARK ( ConcatSimToSimHexC ) - > Name ( " Concat stringa and hex number and literal by e_concat to simstr::stringa " ) ;
BENCHMARK ( ConcatSimToSimHexS ) - > Name ( " Subst stringa and hex number by e_subst literal to simstr::stringa " ) ;
2026-01-31 14:24:12 +00:00
BENCHMARK ( ConcatSimToSimHexVS ) - > Name ( " Subst stringa and hex number by e_vsubst stra to simstr::stringa " ) ;
2026-01-21 11:59:17 +00:00
2026-02-04 14:25:40 +00:00
void ConcatSimToSimOct ( benchmark : : State & state ) {
2026-02-03 07:38:21 +00:00
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
2026-02-08 11:17:03 +00:00
stringa str = " abcdefghihklmopqr " _ss + i / 0x8a010 _fmt + " end " ;
2026-02-03 07:38:21 +00:00
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-02-04 14:25:40 +00:00
void SubstSimToSimOct ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
2026-02-08 11:17:03 +00:00
stringa str = e_subst ( " abcdefghihklmopqr {} end " , i / 0x8a010 _fmt ) ;
2026-02-04 14:25:40 +00:00
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-02-08 11:17:03 +00:00
void VSubstSimToSimOct ( benchmark : : State & state ) {
ssa pattern = " abcdefghihklmopqr {} end " ;
2026-02-03 07:38:21 +00:00
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
2026-02-08 11:17:03 +00:00
stringa str = e_vsubst ( pattern , i / 0x8a010 _fmt ) ;
2026-02-03 07:38:21 +00:00
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-02-08 11:17:03 +00:00
void FormatStdToStdOct ( benchmark : : State & state ) {
2026-02-03 07:38:21 +00:00
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
2026-02-08 11:17:03 +00:00
std : : string str = std : : format ( " abcdefghihklmopqr {:#010o} end " , i ) ;
2026-02-03 07:38:21 +00:00
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-02-04 14:25:40 +00:00
void VFormatStdToStdOct ( benchmark : : State & state ) {
2026-02-08 11:17:03 +00:00
std : : string_view pattern = " abcdefghihklmopqr {:#010o} end " ;
2026-02-03 07:38:21 +00:00
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
std : : string str = std : : vformat ( pattern , std : : make_format_args ( i ) ) ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-02-04 14:25:40 +00:00
void StreamStdToStdOct ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
std : : stringstream strm ;
2026-02-08 11:17:03 +00:00
strm < < " abcdefghihklmopqr 0 " < < std : : oct < < std : : setw ( 9 ) < < std : : setfill ( ' 0 ' ) < < i < < " end " ;
2026-02-04 14:25:40 +00:00
std : : string str = strm . str ( ) ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-02-08 11:17:03 +00:00
void FmtFormatComp ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
std : : string str = fmt : : format ( FMT_COMPILE ( " abcdefghihklmopqr {:#010o} end " ) , i ) ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
void FmtFormat ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
std : : string str = fmt : : format ( " abcdefghihklmopqr {:#010o} end " , i ) ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-02-27 20:05:49 +00:00
void StdFormatSize ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( unsigned i = 1 ; i < = 100'000 ; i * = 10 ) {
size_t len = std : : formatted_size ( " abcdefghihklmopqr {:#010o} end " , i ) ;
2026-03-01 08:15:47 +00:00
std : : string str ;
str . resize_and_overwrite ( len , [ & ] ( char * p , size_t ) {
std : : format_to_n ( str . data ( ) , len , " abcdefghihklmopqr {:#010o} end " , i ) ;
return len ;
} ) ;
2026-02-27 20:05:49 +00:00
benchmark : : DoNotOptimize ( str ) ;
}
}
}
2026-02-08 11:17:03 +00:00
BENCHMARK ( __ ) - > Name ( " ---- format/vformat and subst/vsubst octal number to 32 symbols result ---- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( ConcatSimToSimOct ) - > Name ( " \" abcdefghihklmopqr \" _ss + i / 0x8a010_fmt + \" end \" " ) ;
BENCHMARK ( SubstSimToSimOct ) - > Name ( " e_subst( \" abcdefghihklmopqr {} end \" , i / 0x8a010_fmt) " ) ;
2026-02-04 14:25:40 +00:00
BENCHMARK ( VSubstSimToSimOct ) - > Name ( " e_vsubst(pattern, i / 0x8a010_fmt) " ) ;
2026-02-08 11:17:03 +00:00
BENCHMARK ( FmtFormatComp ) - > Name ( " fmt::format(FMT_COMPILE( \" abcdefghihklmopqr {:#010o} end \" ), i) " ) ;
BENCHMARK ( FmtFormat ) - > Name ( " fmt::format( \" abcdefghihklmopqr {:#010o} end \" , i) " ) ;
BENCHMARK ( FormatStdToStdOct ) - > Name ( " std::format( \" abcdefghihklmopqr {:#010o} end \" , i) " ) ;
2026-02-04 14:25:40 +00:00
BENCHMARK ( VFormatStdToStdOct ) - > Name ( " std::vformat(pattern, std::make_format_args(i)) " ) ;
2026-02-27 20:05:49 +00:00
BENCHMARK ( StdFormatSize ) - > Name ( " std::format with std::formatted_size " ) ;
2026-02-08 11:17:03 +00:00
BENCHMARK ( StreamStdToStdOct ) - > Name ( " strm << \" abcdefghihklmopqr 0 \" << std::oct << std::setw(9) << std::setfill('0') << i << \" end \" " ) ;
2026-02-03 07:38:21 +00:00
2026-01-21 11:59:17 +00:00
void ConcatStdToStdS ( benchmark : : State & state ) {
std : : string s1 = " start " ;
for ( auto _ : state ) {
for ( int i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
std : : string str = s1 + " end " ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
void ConcatSimToStdS ( benchmark : : State & state ) {
std : : string s1 = " start " ;
for ( auto _ : state ) {
for ( int i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
std : : string str = + s1 + " end " ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
void ConcatSimToSimS ( benchmark : : State & state ) {
stra s1 = " start " ;
for ( auto _ : state ) {
for ( int i = 1 ; i < = 100'000 ; i * = 10 ) {
benchmark : : DoNotOptimize ( s1 ) ;
stringa str = s1 + " end " ;
benchmark : : DoNotOptimize ( str ) ;
}
}
}
BENCHMARK ( __ ) - > Name ( " ----- Concatenate string + \" Literal \" --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( ConcatStdToStdS ) - > Name ( " Concat std::string by std to std::string " ) ;
BENCHMARK ( ConcatSimToStdS ) - > Name ( " Concat std::string by StrExpr to std::string " ) ;
BENCHMARK ( ConcatSimToSimS ) - > Name ( " Concat stringa by StrExpr to stringa " ) ;
size_t find_pos_str ( std : : string_view src , std : : string_view name ) {
// before C++26 we can not concatenate string and string_view...
return src . find ( " \n - " s + std : : string { name } + " - \n " ) ;
}
size_t find_pos_exp ( ssa src , ssa name ) {
return src . find ( std : : string { " \n - " + name + " - \n " } ) ;
}
size_t find_pos_sim ( ssa src , ssa name ) {
return src . find ( lstringa < 200 > { " \n - " + name + " - \n " } ) ;
}
2026-02-14 10:09:54 +00:00
size_t find_pos_sz ( sz : : string_view src , sz : : string_view name ) {
return src . find ( sz : : string { " \n - " } . append ( name ) . append ( " - \n " ) ) ;
}
2026-01-21 11:59:17 +00:00
//> size_t find_pos_str(std::string_view src, std::string_view name) {
void FindConcatThreeStr ( benchmark : : State & state ) {
std : : string_view src = " sdfsdf \n - testtesttesttesttesttesttestte - \n sfrgdgfsg " ;
std : : string_view fnd = " testtesttesttesttesttesttestte " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( src ) ;
benchmark : : DoNotOptimize ( fnd ) ;
size_t pos = find_pos_str ( src , fnd ) ;
benchmark : : DoNotOptimize ( pos ) ;
# ifdef CHECK_RESULT
if ( pos ! = 6 ) {
state . SkipWithError ( " fail " ) ;
}
# endif
}
}
//> size_t find_pos_exp(ssa src, ssa name) {
void FindConcatThreeExp ( benchmark : : State & state ) {
std : : string_view src = " sdfsdf \n - testtesttesttesttesttesttestte - \n sfrgdgfsg " ;
std : : string_view fnd = " testtesttesttesttesttesttestte " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( src ) ;
benchmark : : DoNotOptimize ( fnd ) ;
size_t pos = find_pos_exp ( src , fnd ) ;
benchmark : : DoNotOptimize ( pos ) ;
# ifdef CHECK_RESULT
if ( pos ! = 6 ) {
state . SkipWithError ( " fail " ) ;
}
# endif
}
}
//> size_t find_pos_sim(ssa src, ssa name) {
void FindConcatThreeSim ( benchmark : : State & state ) {
ssa src = " sdfsdf \n - testtesttesttesttesttesttestte - \n sfrgdgfsg " ;
ssa fnd = " testtesttesttesttesttesttestte " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( src ) ;
benchmark : : DoNotOptimize ( fnd ) ;
size_t pos = find_pos_sim ( src , fnd ) ;
benchmark : : DoNotOptimize ( pos ) ;
# ifdef CHECK_RESULT
if ( pos ! = 6 ) {
state . SkipWithError ( " fail " ) ;
}
# endif
}
}
2026-02-14 10:09:54 +00:00
//> size_t find_pos_sz(sz::string_view src, sz::string_view name) {
void FindConcatThreeSz ( benchmark : : State & state ) {
sz : : string_view src = " sdfsdf \n - testtesttesttesttesttesttestte - \n sfrgdgfsg " ;
sz : : string_view fnd = " testtesttesttesttesttesttestte " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( src ) ;
benchmark : : DoNotOptimize ( fnd ) ;
size_t pos = find_pos_sz ( src , fnd ) ;
benchmark : : DoNotOptimize ( pos ) ;
# ifdef CHECK_RESULT
if ( pos ! = 6 ) {
state . SkipWithError ( " fail " ) ;
}
# endif
}
}
2026-01-21 11:59:17 +00:00
BENCHMARK ( __ ) - > Name ( " ----- Find three concatenated string in string_view ----- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( FindConcatThreeStr ) - > Name ( " Find concat three std::string " ) ;
BENCHMARK ( FindConcatThreeExp ) - > Name ( " Find concat three strexpr " ) ;
BENCHMARK ( FindConcatThreeSim ) - > Name ( " Find concat three simstr " ) ;
2026-02-14 10:09:54 +00:00
BENCHMARK ( FindConcatThreeSz ) - > Name ( " Find concat three stringzilla string " ) ;
2026-01-21 11:59:17 +00:00
std : : string buildTypeNameStr ( std : : string_view type_name , size_t prec , size_t scale ) {
std : : string res { type_name } ;
if ( prec ) {
res + = " ( " + std : : to_string ( prec ) ;
if ( scale ) {
res + = " , " + std : : to_string ( scale ) ;
}
res + = " ) " ;
}
return res ;
}
std : : string buildTypeNameExp ( ssa type_name , size_t prec , size_t scale ) {
if ( prec ) {
return type_name + " ( " + prec + e_if ( scale , " , " _ss + scale ) + " ) " ;
}
return type_name ;
}
stringa buildTypeNameSim ( ssa type_name , size_t prec , size_t scale ) {
if ( prec ) {
return type_name + " ( " + prec + e_if ( scale , " , " _ss + scale ) + " ) " ;
}
return type_name ;
}
//> std::string buildTypeNameStr(std::string_view type_name, size_t prec, size_t scale) {
void BuildTypeNameStr ( benchmark : : State & state ) {
std : : string_view type_name = " numeric " ;
size_t prec = state . range ( 0 ) , scale = prec / 2 ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( type_name ) ;
benchmark : : DoNotOptimize ( prec ) ;
benchmark : : DoNotOptimize ( scale ) ;
std : : string res = buildTypeNameStr ( type_name , prec , scale ) ;
benchmark : : DoNotOptimize ( res ) ;
}
}
//> std::string buildTypeNameExp(ssa type_name, size_t prec, size_t scale) {
void BuildTypeNameExp ( benchmark : : State & state ) {
std : : string_view type_name = " numeric " ;
size_t prec = state . range ( 0 ) , scale = prec / 2 ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( type_name ) ;
benchmark : : DoNotOptimize ( prec ) ;
benchmark : : DoNotOptimize ( scale ) ;
std : : string res = buildTypeNameExp ( type_name , prec , scale ) ;
benchmark : : DoNotOptimize ( res ) ;
}
}
//> stringa buildTypeNameSim(ssa type_name, size_t prec, size_t scale) {
void BuildTypeNameSim ( benchmark : : State & state ) {
ssa type_name = " numeric " ;
size_t prec = state . range ( 0 ) , scale = prec / 2 ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( type_name ) ;
benchmark : : DoNotOptimize ( prec ) ;
benchmark : : DoNotOptimize ( scale ) ;
stringa res = buildTypeNameSim ( type_name , prec , scale ) ;
benchmark : : DoNotOptimize ( res ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ----- Build Type Name --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( BuildTypeNameStr ) - > Name ( " BuildTypeNameStr 0 " ) - > Arg ( 0 ) ;
BENCHMARK ( BuildTypeNameExp ) - > Name ( " BuildTypeNameExp 0 " ) - > Arg ( 0 ) ;
BENCHMARK ( BuildTypeNameSim ) - > Name ( " BuildTypeNameSim 0 " ) - > Arg ( 0 ) ;
BENCHMARK ( BuildTypeNameStr ) - > Name ( " BuildTypeNameStr 10 " ) - > Arg ( 10 ) ;
BENCHMARK ( BuildTypeNameExp ) - > Name ( " BuildTypeNameExp 10 " ) - > Arg ( 10 ) ;
BENCHMARK ( BuildTypeNameSim ) - > Name ( " BuildTypeNameSim 10 " ) - > Arg ( 10 ) ;
std : : string make_str_str ( std : : string_view from , std : : string_view pattern , std : : string_view repl ) {
auto str_replace = [ ] ( std : : string_view from , std : : string_view pattern , std : : string_view repl ) {
std : : string result ;
for ( size_t offset = 0 ; ; ) {
size_t pos = from . find ( pattern , offset ) ;
if ( pos = = std : : string : : npos ) {
result + = from . substr ( offset ) ;
break ;
}
result + = from . substr ( offset , pos - offset ) ;
result + = repl ;
offset = pos + pattern . length ( ) ;
}
return result ;
} ;
return " < " + str_replace ( from , pattern , repl ) + " > " ;
}
std : : string make_str_exp ( std : : string_view from , std : : string_view pattern , std : : string_view repl ) {
return " < " + e_repl ( from , pattern , repl ) + " > " ;
}
//> std::string make_str_str(std::string_view from, std::string_view pattern, std::string_view repl) {
void ReplaceStr ( benchmark : : State & state ) {
std : : string_view from = " testitestitestitesti " , what = " te " , repl = " --+-- " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( from ) ;
benchmark : : DoNotOptimize ( what ) ;
benchmark : : DoNotOptimize ( repl ) ;
std : : string res = make_str_str ( from , what , repl ) ;
benchmark : : DoNotOptimize ( res ) ;
}
}
//> std::string make_str_exp(std::string_view from, std::string_view pattern, std::string_view repl) {
void ReplaceExp ( benchmark : : State & state ) {
std : : string_view from = " testitestitestitesti " , what = " te " , repl = " --+-- " ;
for ( auto _ : state ) {
benchmark : : DoNotOptimize ( from ) ;
benchmark : : DoNotOptimize ( what ) ;
benchmark : : DoNotOptimize ( repl ) ;
std : : string res = make_str_exp ( from , what , repl ) ;
benchmark : : DoNotOptimize ( res ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ----- Replace string by copy ----- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( ReplaceStr ) - > Name ( " Concat with replace str " ) ;
BENCHMARK ( ReplaceExp ) - > Name ( " Concat with replace exp " ) ;
2025-04-05 14:21:11 +00:00
template < typename T >
void CreateEmpty ( benchmark : : State & state ) {
for ( auto _ : state ) {
T empty_string ;
benchmark : : DoNotOptimize ( empty_string ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ----- Create Empty Str --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( CreateEmpty < std : : string > ) - > Name ( " std::string e; " ) ;
BENCHMARK ( CreateEmpty < std : : string_view > ) - > Name ( " std::string_view e; " ) ;
BENCHMARK ( CreateEmpty < ssa > ) - > Name ( " ssa e; " ) ;
BENCHMARK ( CreateEmpty < stringa > ) - > Name ( " stringa e; " ) ;
BENCHMARK ( CreateEmpty < lstringa < 20 > > ) - > Name ( " lstringa<20> e; " ) ;
BENCHMARK ( CreateEmpty < lstringa < 40 > > ) - > Name ( " lstringa<40> e; " ) ;
template < typename T >
void CreateShortLiteral ( benchmark : : State & state ) {
for ( auto _ : state ) {
T empty_string = TEST_TEXT ;
benchmark : : DoNotOptimize ( empty_string ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ----- Create Str from short literal (9 symbols) -------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( CreateShortLiteral < std : : string > ) - > Name ( " std::string e = \" Test text \" ; " ) ;
BENCHMARK ( CreateShortLiteral < std : : string_view > ) - > Name ( " std::string_view e = \" Test text \" ; " ) ;
BENCHMARK ( CreateShortLiteral < ssa > ) - > Name ( " ssa e = \" Test text \" ; " ) ;
BENCHMARK ( CreateShortLiteral < stringa > ) - > Name ( " stringa e = \" Test text \" ; " ) ;
BENCHMARK ( CreateShortLiteral < lstringa < 20 > > ) - > Name ( " lstringa<20> e = \" Test text \" ; " ) ;
BENCHMARK ( CreateShortLiteral < lstringa < 40 > > ) - > Name ( " lstringa<40> e = \" Test text \" ; " ) ;
template < typename T >
void CreateLongLiteral ( benchmark : : State & state ) {
for ( auto _ : state ) {
T empty_string { LONG_TEXT } ;
benchmark : : DoNotOptimize ( empty_string ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ----- Create Str from long literal (30 symbols) --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( CreateLongLiteral < std : : string > ) - > Name ( " std::string e = \" 123456789012345678901234567890 \" ; " ) ;
BENCHMARK ( CreateLongLiteral < std : : string_view > ) - > Name ( " std::string_view e = \" 123456789012345678901234567890 \" ; " ) ;
BENCHMARK ( CreateLongLiteral < ssa > ) - > Name ( " ssa e = \" 123456789012345678901234567890 \" ; " ) ;
BENCHMARK ( CreateLongLiteral < stringa > ) - > Name ( " stringa e = \" 123456789012345678901234567890 \" ; " ) ;
BENCHMARK ( CreateLongLiteral < lstringa < 20 > > ) - > Name ( " lstringa<20> e = \" 123456789012345678901234567890 \" ; " ) ;
BENCHMARK ( CreateLongLiteral < lstringa < 40 > > ) - > Name ( " lstringa<40> e = \" 123456789012345678901234567890 \" ; " ) ;
template < typename T >
void CopyShortString ( benchmark : : State & state ) {
T x { TEST_TEXT } ;
for ( auto _ : state ) {
T copy { x } ;
benchmark : : DoNotOptimize ( copy ) ;
benchmark : : DoNotOptimize ( x ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ----- Create copy of Str with 9 symbols --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( CopyShortString < std : : string > ) - > Name ( " std::string e = \" Test text \" ; auto c{e}; " ) ;
BENCHMARK ( CopyShortString < std : : string_view > ) - > Name ( " std::string_view e = \" Test text \" ; auto c{e}; " ) ;
BENCHMARK ( CopyShortString < ssa > ) - > Name ( " ssa e = \" Test text \" ; auto c{e}; " ) ;
BENCHMARK ( CopyShortString < stringa > ) - > Name ( " stringa e = \" Test text \" ; auto c{e}; " ) ;
BENCHMARK ( CopyShortString < lstringa < 20 > > ) - > Name ( " lstringa<20> e = \" Test text \" ; auto c{e}; " ) ;
BENCHMARK ( CopyShortString < lstringa < 40 > > ) - > Name ( " lstringa<40> e = \" Test text \" ; auto c{e}; " ) ;
template < typename T >
void CopyLongString ( benchmark : : State & state ) {
T x = LONG_TEXT ;
for ( auto _ : state ) {
T copy { x } ;
benchmark : : DoNotOptimize ( copy ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ----- Create copy of Str with 30 symbols --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( CopyLongString < std : : string > ) - > Name ( " std::string e = \" 123456789012345678901234567890 \" ; auto c{e}; " ) ;
BENCHMARK ( CopyLongString < std : : string_view > ) - > Name ( " std::string_view e = \" 123456789012345678901234567890 \" ; auto c{e}; " ) ;
BENCHMARK ( CopyLongString < ssa > ) - > Name ( " ssa e = \" 123456789012345678901234567890 \" ; auto c{e}; " ) ;
BENCHMARK ( CopyLongString < stringa > ) - > Name ( " stringa e = \" 123456789012345678901234567890 \" ; auto c{e}; " ) ;
BENCHMARK ( CopyLongString < lstringa < 20 > > ) - > Name ( " lstringa<20> e = \" 123456789012345678901234567890 \" ; auto c{e}; " ) ;
BENCHMARK ( CopyLongString < lstringa < 40 > > ) - > Name ( " lstringa<40> e = \" 123456789012345678901234567890 \" ; auto c{e}; " ) ;
template < typename T >
void Find ( benchmark : : State & state ) {
T x { LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT } ;
for ( auto _ : state ) {
int i = ( int ) x . find ( TEST_TEXT ) ;
# ifdef CHECK_RESULT
if ( i ! = 90 ) {
state . SkipWithError ( " not find? " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( i ) ;
benchmark : : DoNotOptimize ( x ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ----- Find 9 symbols text in end of 99 symbols text --------- " ) - > Repetitions ( 1 ) ;
2026-02-14 10:09:54 +00:00
BENCHMARK ( Find < sz : : string > ) - > Name ( " sz::string::find; " ) ;
2025-04-05 14:21:11 +00:00
BENCHMARK ( Find < std : : string > ) - > Name ( " std::string::find; " ) ;
BENCHMARK ( Find < std : : string_view > ) - > Name ( " std::string_view::find; " ) ;
BENCHMARK ( Find < ssa > ) - > Name ( " ssa::find; " ) ;
BENCHMARK ( Find < stringa > ) - > Name ( " stringa::find; " ) ;
BENCHMARK ( Find < lstringa < 20 > > ) - > Name ( " lstringa<20>::find; " ) ;
BENCHMARK ( Find < lstringa < 40 > > ) - > Name ( " lstringa<40>::find; " ) ;
template < typename T >
void CopyDynString ( benchmark : : State & state ) {
T x ( state . range ( 0 ) , ' a ' ) ;
for ( auto _ : state ) {
T copy { x } ;
benchmark : : DoNotOptimize ( copy ) ;
benchmark : : DoNotOptimize ( x ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ------- Copy not literal Str with N symbols --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( CopyDynString < std : : string > ) - > Name ( " std::string copy{str_with_len_N}; " ) - > Arg ( 15 ) - > Arg ( 16 ) - > Arg ( 23 ) - > Arg ( 24 ) - > RangeMultiplier ( 2 ) - > Range ( 32 , 4096 ) ;
BENCHMARK ( CopyDynString < stringa > ) - > Name ( " stringa copy{str_with_len_N}; " ) - > Arg ( 15 ) - > Arg ( 16 ) - > Arg ( 23 ) - > Arg ( 24 ) - > RangeMultiplier ( 2 ) - > Range ( 32 , 4096 ) ;
BENCHMARK ( CopyDynString < lstringa < 16 > > ) - > Name ( " lstringa<16> copy{str_with_len_N}; " ) - > Arg ( 15 ) - > Arg ( 16 ) - > Arg ( 23 ) - > Arg ( 24 ) - > RangeMultiplier ( 2 ) - > Range ( 32 , 4096 ) ;
BENCHMARK ( CopyDynString < lstringa < 512 > > ) - > Name ( " lstringa<512> copy{str_with_len_N}; " ) - > Arg ( 15 ) - > Arg ( 16 ) - > Arg ( 23 ) - > Arg ( 24 ) - > RangeMultiplier ( 2 ) - > Range ( 32 , 4096 ) ;
void ToIntStr10 ( benchmark : : State & state , const std : : string & s , int c ) {
for ( auto _ : state ) {
int res = std : : strtol ( s . c_str ( ) , nullptr , 10 ) ;
# ifdef CHECK_RESULT
if ( res ! = c ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
}
}
void ToIntStr16 ( benchmark : : State & state , const std : : string & s , int c ) {
for ( auto _ : state ) {
int res = std : : strtol ( s . c_str ( ) , nullptr , 16 ) ;
# ifdef CHECK_RESULT
if ( res ! = c ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
}
}
void ToIntStr0 ( benchmark : : State & state , const std : : string & s , int c ) {
for ( auto _ : state ) {
int res = std : : strtol ( s . c_str ( ) , nullptr , 0 ) ;
# ifdef CHECK_RESULT
if ( res ! = c ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
}
}
void ToIntFromChars10 ( benchmark : : State & state , const std : : string_view & s , int c ) {
for ( auto _ : state ) {
int res = 0 ;
std : : from_chars ( s . data ( ) , s . data ( ) + s . size ( ) , res , 10 ) ;
# ifdef CHECK_RESULT
if ( res ! = c ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
}
}
void ToIntFromChars16 ( benchmark : : State & state , const std : : string_view & s , int c ) {
for ( auto _ : state ) {
int res = 0 ;
std : : from_chars ( s . data ( ) , s . data ( ) + s . size ( ) , res , 16 ) ;
# ifdef CHECK_RESULT
if ( res ! = c ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
}
}
template < typename T >
void ToIntSimStr10 ( benchmark : : State & state , T t , int c ) {
for ( auto _ : state ) {
2025-11-26 19:15:50 +00:00
int res = t . template to_int < int , true , 10 , false , false > ( ) . value ;
2025-04-05 14:21:11 +00:00
# ifdef CHECK_RESULT
if ( res ! = c ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
benchmark : : DoNotOptimize ( t ) ;
}
}
template < typename T >
void ToIntSimStr16 ( benchmark : : State & state , T t , int c ) {
for ( auto _ : state ) {
2025-11-26 19:15:50 +00:00
int res = t . template to_int < int , true , 16 , false , false > ( ) . value ;
2025-04-05 14:21:11 +00:00
# ifdef CHECK_RESULT
if ( res ! = c ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
benchmark : : DoNotOptimize ( t ) ;
}
}
template < typename T >
void ToIntSimStr0 ( benchmark : : State & state , T t , int c ) {
for ( auto _ : state ) {
2025-11-26 19:15:50 +00:00
int res = t . template to_int < int > ( ) . value ;
2025-04-05 14:21:11 +00:00
# ifdef CHECK_RESULT
if ( res ! = c ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
benchmark : : DoNotOptimize ( t ) ;
}
}
void ToIntNoOverflow ( benchmark : : State & state , ssa t , int c ) {
for ( auto _ : state ) {
2025-11-26 19:15:50 +00:00
int res = t . to_int < int , false > ( ) . value ;
2025-04-05 14:21:11 +00:00
# ifdef CHECK_RESULT
if ( res ! = c ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
benchmark : : DoNotOptimize ( t ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ----- Convert to int '1234567' --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK_CAPTURE ( ToIntStr10 , , std : : string { " 123456789 " } , 123456789 ) - > Name ( " std::string s = \" 123456789 \" ; int res = std::strtol(s.c_str(), 0, 10); " ) ;
BENCHMARK_CAPTURE ( ToIntFromChars10 , , std : : string_view { " 123456789 " } , 123456789 ) - > Name ( " std::string_view s = \" 123456789 \" ; std::from_chars(s.data(), s.data() + s.size(), res, 10); " ) ;
BENCHMARK_CAPTURE ( ToIntSimStr10 , , stringa { " 123456789 " } , 123456789 ) - > Name ( " stringa s = \" 123456789 \" ; int res = s.to_int<int, true, 10, false> " ) ;
BENCHMARK_CAPTURE ( ToIntSimStr10 , , ssa { " 123456789 " } , 123456789 ) - > Name ( " ssa s = \" 123456789 \" ; int res = s.to_int<int, true, 10, false> " ) ;
BENCHMARK_CAPTURE ( ToIntSimStr10 , , lstringa < 20 > { " 123456789 " } , 123456789 ) - > Name ( " lstringa<20> s = \" 123456789 \" ; int res = s.to_int<int, true, 10, false> " ) ;
BENCHMARK ( __ ) - > Name ( " ----- Convert to unsigned 'abcDef' --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK_CAPTURE ( ToIntStr16 , , std : : string { " abcDef " } , 0xabcDef ) - > Name ( " std::string s = \" abcDef \" ; int res = std::strtol(s.c_str(), 0, 16); " ) ;
BENCHMARK_CAPTURE ( ToIntFromChars16 , , std : : string_view { " abcDef " } , 0xabcDef ) - > Name ( " std::string_view s = \" abcDef \" ; std::from_chars(s.data(), s.data() + s.size(), res, 16); " ) ;
BENCHMARK_CAPTURE ( ToIntSimStr16 , , stringa { " abcDef " } , 0xabcDef ) - > Name ( " stringa s = \" abcDef \" ; int res = s.to_int<int, true, 16, false> " ) ;
BENCHMARK_CAPTURE ( ToIntSimStr16 , , ssa { " abcDef " } , 0xabcDef ) - > Name ( " ssa s = \" abcDef \" ; int res = s.to_int<int, true, 16, false> " ) ;
BENCHMARK_CAPTURE ( ToIntSimStr16 , > , lstringa < 20 > { " abcDef " } , 0xabcDef ) - > Name ( " lstringa<20> s = \" abcDef \" ; int res = s.to_int<int, true, 16, false> " ) ;
BENCHMARK ( __ ) - > Name ( " ----- Convert to int ' 1234567' --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK_CAPTURE ( ToIntStr0 , , std : : string { " 123456789 " } , 123456789 ) - > Name ( " std::string s = \" 123456789 \" ; int res = std::strtol(s.c_str(), 0, 0); " ) ;
BENCHMARK_CAPTURE ( ToIntSimStr0 , , stringa { " 123456789 " } , 123456789 ) - > Name ( " stringa s = \" 123456789 \" ; int res = s.to_int<int>; // Check overflow " ) ;
BENCHMARK_CAPTURE ( ToIntNoOverflow , , ssa { " 123456789 " } , 123456789 ) - > Name ( " ssa s = \" 123456789 \" ; int res = s.to_int<int, false>; // No check overflow " ) ;
2025-11-26 19:15:50 +00:00
void ToDoubleStr ( benchmark : : State & state , const std : : string & s , double c ) {
for ( auto _ : state ) {
char * ptr = nullptr ;
double res = std : : strtod ( s . c_str ( ) , & ptr ) ;
if ( ptr = = s . c_str ( ) ) {
state . SkipWithError ( " not equal " ) ;
}
# ifdef CHECK_RESULT
if ( res ! = c ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
}
}
2026-02-27 20:05:49 +00:00
template < typename K = char >
2025-11-26 19:15:50 +00:00
void ToDoubleFromChars ( benchmark : : State & state , const std : : string_view & s , double c ) {
for ( auto _ : state ) {
double res = 0 ;
2026-02-27 20:05:49 +00:00
if constexpr ( requires { std : : from_chars ( std : : declval < K * > ( ) , std : : declval < K * > ( ) , std : : declval < double & > ( ) ) ; } ) {
if ( std : : from_chars ( ( const K * ) s . data ( ) , ( const K * ) s . data ( ) + s . size ( ) , res ) . ec ! = std : : errc { } ) {
state . SkipWithError ( " not equal " ) ;
}
} else {
state . SkipWithError ( " not implemented " ) ;
2025-11-26 19:15:50 +00:00
}
# ifdef CHECK_RESULT
if ( res ! = c ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
}
}
template < typename T >
void ToDoubleSimStr ( benchmark : : State & state , T t , double c ) {
for ( auto _ : state ) {
auto r = t . template to_double < false > ( ) ;
if ( ! r ) {
state . SkipWithError ( " not equal " ) ;
}
double res = * r ;
# ifdef CHECK_RESULT
if ( res ! = c ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
benchmark : : DoNotOptimize ( t ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ----- Convert to double '1234.567e10' --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK_CAPTURE ( ToDoubleStr , , std : : string { " 1234.567e10 " } , 1234.567e10 ) - > Name ( " std::string s = \" 1234.567e10 \" ; double res = std::strtod(s.c_str(), nullptr); " ) ;
BENCHMARK_CAPTURE ( ToDoubleFromChars , , std : : string_view { " 1234.567e10 " } , 1234.567e10 ) - > Name ( " std::string_view s = \" 1234.567e10 \" ; std::from_chars(s.data(), s.data() + s.size(), res); " ) ;
BENCHMARK_CAPTURE ( ToDoubleSimStr , , ssa { " 1234.567e10 " } , 1234.567e10 ) - > Name ( " ssa s = \" 1234.567e10 \" ; double res = *s.to_double() " ) ;
2025-04-05 14:21:11 +00:00
void AppendStreamConstLiteral ( benchmark : : State & state ) {
for ( auto _ : state ) {
std : : string result ;
std : : stringstream str ;
for ( size_t c = 0 ; c < 64 ; c + + ) {
str < < TEXT_16 ;
}
result = str . str ( ) ;
# ifdef CHECK_RESULT
if ( result . size ( ) ! = 1024 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( str ) ;
}
}
void AppendStdStringConstLiteral ( benchmark : : State & state ) {
for ( auto _ : state ) {
std : : string result ;
for ( size_t c = 0 ; c < 64 ; c + + ) {
result + = TEXT_16 ;
}
# ifdef CHECK_RESULT
if ( result . size ( ) ! = 1024 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
}
}
template < unsigned N >
void AppendLstringConstLiteral ( benchmark : : State & state ) {
for ( auto _ : state ) {
lstringa < N > result ;
for ( size_t c = 0 ; c < 64 ; c + + ) {
result + = TEXT_16 ;
}
# ifdef CHECK_RESULT
if ( result . length ( ) ! = 1024 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
}
}
BENCHMARK ( __ ) - > Name ( " -- Append const literal of 16 bytes 64 times, 1024 total length -- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( AppendStreamConstLiteral ) - > Name ( " std::stringstream str; ... str << \" abbaabbaabbaabba \" ; " ) ;
BENCHMARK ( AppendStdStringConstLiteral ) - > Name ( " std::string str; ... str += \" abbaabbaabbaabba \" ; " ) ;
BENCHMARK ( AppendLstringConstLiteral < 8 > ) - > Name ( " lstringa<8> str; ... str += \" abbaabbaabbaabba \" ; " ) ;
BENCHMARK ( AppendLstringConstLiteral < 128 > ) - > Name ( " lstringa<128> str; ... str += \" abbaabbaabbaabba \" ; " ) ;
BENCHMARK ( AppendLstringConstLiteral < 512 > ) - > Name ( " lstringa<512> str; ... str += \" abbaabbaabbaabba \" ; " ) ;
BENCHMARK ( AppendLstringConstLiteral < 1024 > ) - > Name ( " lstringa<1024> str; ... str += \" abbaabbaabbaabba \" ; " ) ;
void AppendStreamStrConstLiteral ( benchmark : : State & state ) {
std : : string s1 = TEXT_16 ;
for ( auto _ : state ) {
std : : string result ;
std : : stringstream s ;
for ( size_t c = 0 ; c < 32 ; c + + ) {
s < < s1 < < TEXT_16 ;
}
result = s . str ( ) ;
# ifdef CHECK_RESULT
if ( result . size ( ) ! = 1024 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( s1 ) ;
}
}
void AppendStdStrStrConstLiteral ( benchmark : : State & state ) {
std : : string p1 = TEXT_16 ;
for ( auto _ : state ) {
std : : string result ;
for ( size_t c = 0 ; c < 32 ; c + + ) {
result + = p1 + TEXT_16 ;
}
# ifdef CHECK_RESULT
if ( result . size ( ) ! = 1024 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( p1 ) ;
}
}
template < unsigned N >
void AppendLstringStrConstLiteral ( benchmark : : State & state ) {
stringa p1 = TEXT_16 ;
for ( auto _ : state ) {
lstringa < N > result ;
for ( size_t c = 0 ; c < 32 ; c + + ) {
result + = p1 + TEXT_16 ;
}
# ifdef CHECK_RESULT
if ( result . length ( ) ! = 1024 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( p1 ) ;
}
}
BENCHMARK ( __ ) - > Name ( " -- Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length -- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( AppendStreamStrConstLiteral ) - > Name ( " std::stringstream str; ... str << str_var << \" abbaabbaabbaabba \" ; " ) ;
BENCHMARK ( AppendStdStrStrConstLiteral ) - > Name ( " std::string str; ... str += str_var + \" abbaabbaabbaabba \" ; " ) ;
BENCHMARK ( AppendLstringStrConstLiteral < 8 > ) - > Name ( " lstringa<8> str; ... str += str_var + \" abbaabbaabbaabba \" ; " ) ;
BENCHMARK ( AppendLstringStrConstLiteral < 128 > ) - > Name ( " lstringa<128> str; ... str += str_var + \" abbaabbaabbaabba \" ; " ) ;
BENCHMARK ( AppendLstringStrConstLiteral < 512 > ) - > Name ( " lstringa<512> str; ... str += str_var + \" abbaabbaabbaabba \" ; " ) ;
BENCHMARK ( AppendLstringStrConstLiteral < 1024 > ) - > Name ( " lstringa<1024> str; ... str += str_var + \" abbaabbaabbaabba \" ; " ) ;
void AppendStreamStrConstLiteralBig ( benchmark : : State & state ) {
std : : string s1 = TEXT_16 ;
for ( auto _ : state ) {
std : : string result ;
std : : stringstream s ;
for ( size_t c = 0 ; c < 2048 ; c + + ) {
s < < s1 < < TEXT_16 ;
}
result = s . str ( ) ;
# ifdef CHECK_RESULT
if ( result . size ( ) ! = 1024 * 64 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( s1 ) ;
}
}
void AppendStdStrStrConstLiteralBig ( benchmark : : State & state ) {
std : : string p1 = TEXT_16 ;
for ( auto _ : state ) {
std : : string result ;
for ( size_t c = 0 ; c < 2048 ; c + + ) {
result + = p1 + TEXT_16 ;
}
# ifdef CHECK_RESULT
if ( result . size ( ) ! = 1024 * 64 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( p1 ) ;
}
}
template < unsigned N >
void AppendLstringStrConstLiteralBig ( benchmark : : State & state ) {
stringa p1 = TEXT_16 ;
for ( auto _ : state ) {
lstringa < N > result ;
for ( size_t c = 0 ; c < 2048 ; c + + ) {
result + = p1 + TEXT_16 ;
}
# ifdef CHECK_RESULT
if ( result . length ( ) ! = 1024 * 64 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( p1 ) ;
}
}
BENCHMARK ( __ ) - > Name ( " -- Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length -- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( AppendStreamStrConstLiteralBig ) - > Name ( " std::stringstream str; ... str << str_var << \" abbaabbaabbaabba \" ; 2048 times " ) ;
BENCHMARK ( AppendStdStrStrConstLiteralBig ) - > Name ( " std::string str; ... str += str_var + \" abbaabbaabbaabba \" ; 2048 times " ) ;
BENCHMARK ( AppendLstringStrConstLiteralBig < 8 > ) - > Name ( " lstringa<8> str; ... str += str_var + \" abbaabbaabbaabba \" ; 2048 times " ) ;
BENCHMARK ( AppendLstringStrConstLiteralBig < 128 > ) - > Name ( " lstringa<128> str; ... str += str_var + \" abbaabbaabbaabba \" ; 2048 times " ) ;
BENCHMARK ( AppendLstringStrConstLiteralBig < 512 > ) - > Name ( " lstringa<512> str; ... str += str_var + \" abbaabbaabbaabba \" ; 2048 times " ) ;
BENCHMARK ( AppendLstringStrConstLiteralBig < 1024 > ) - > Name ( " lstringa<1024> str; ... str += str_var + \" abbaabbaabbaabba \" ; 2048 times " ) ;
void AppendStream2String ( benchmark : : State & state ) {
std : : string s1 = TEXT_16 ;
std : : string s2 = TEXT_16 ;
for ( auto _ : state ) {
std : : string result ;
std : : stringstream s ;
for ( size_t c = 0 ; c < 32 ; c + + ) {
s < < s1 < < s2 ;
}
result = s . str ( ) ;
# ifdef CHECK_RESULT
if ( result . size ( ) ! = 1024 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( s1 ) ;
benchmark : : DoNotOptimize ( s2 ) ;
}
}
void AppendStdStr2String ( benchmark : : State & state ) {
std : : string s1 = TEXT_16 ;
std : : string s2 = TEXT_16 ;
2025-11-25 15:55:16 +00:00
2025-04-05 14:21:11 +00:00
for ( auto _ : state ) {
std : : string result ;
for ( size_t c = 0 ; c < 32 ; c + + ) {
result + = s1 + s2 ;
}
# ifdef CHECK_RESULT
if ( result . size ( ) ! = 1024 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( s1 ) ;
benchmark : : DoNotOptimize ( s2 ) ;
}
}
template < unsigned N >
void AppendLstring2String ( benchmark : : State & state ) {
stra s1 = TEXT_16 ;
stra s2 = TEXT_16 ;
for ( auto _ : state ) {
lstringa < N > result ;
for ( size_t c = 0 ; c < 32 ; c + + ) {
result + = s1 + s2 ;
}
# ifdef CHECK_RESULT
if ( result . length ( ) ! = 1024 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( s1 ) ;
benchmark : : DoNotOptimize ( s2 ) ;
}
}
BENCHMARK ( __ ) - > Name ( " -- Append 2 string of 16 bytes 32 times, 1024 total length -- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( AppendStream2String ) - > Name ( " std::stringstream str; ... str << str_var1 << str_var2; " ) ;
BENCHMARK ( AppendStdStr2String ) - > Name ( " std::string str; ... str += str_var1 + str_var2; " ) ;
BENCHMARK ( AppendLstring2String < 8 > ) - > Name ( " lstringa<16> str; ... str += str_var1 + str_var2; " ) ;
BENCHMARK ( AppendLstring2String < 128 > ) - > Name ( " lstringa<128> str; ... str += str_var1 + str_var2; " ) ;
BENCHMARK ( AppendLstring2String < 512 > ) - > Name ( " lstringa<512> str; ... str += str_var1 + str_var2; " ) ;
BENCHMARK ( AppendLstring2String < 1024 > ) - > Name ( " lstringa<1024> str; ... str += str_var1 + str_var2; " ) ;
void AppendStreamStrNumStr ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( unsigned k = 1 ; k < = 1'000'000'000 ; k * = 10 ) {
std : : stringstream t ;
t < < " test = " < < k < < " times " ;
std : : string result = t . str ( ) ;
# ifdef CHECK_RESULT
if ( ! result . starts_with ( " test = " ) | | ! result . ends_with ( " times " ) ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( k ) ;
}
}
}
void AppendStdStringStrNumStr ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( unsigned k = 1 ; k < = 1'000'000'000 ; k * = 10 ) {
std : : string result = " test = " + std : : to_string ( k ) + " times " ;
# ifdef CHECK_RESULT
if ( ! result . starts_with ( " test = " ) | | ! result . ends_with ( " times " ) ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( k ) ;
}
}
}
void AppendSprintfStrNumStr ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( unsigned k = 1 ; k < = 1'000'000'000 ; k * = 10 ) {
char buf [ 100 ] ;
std : : sprintf ( buf , " test = %u times " , k ) ;
std : : string result = buf ;
# ifdef CHECK_RESULT
if ( ! result . starts_with ( " test = " ) | | ! result . ends_with ( " times " ) ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( k ) ;
}
}
}
void AppendFormatStrNumStr ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( unsigned k = 1 ; k < = 1'000'000'000 ; k * = 10 ) {
std : : string result = std : : format ( " test = {} times " , k ) ;
# ifdef CHECK_RESULT
if ( ! result . starts_with ( " test = " ) | | ! result . ends_with ( " times " ) ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( k ) ;
}
}
}
template < typename T >
void AppendSimStrStrNumStrF ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( unsigned k = 1 ; k < = 1'000'000'000 ; k * = 10 ) {
T result ;
result . format ( " test = {} times " , k ) ;
# ifdef CHECK_RESULT
if ( ! result . starts_with ( " test = " ) | | ! result . ends_with ( " times " ) ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( k ) ;
}
}
}
template < typename T >
void AppendSimStrStrNumStr ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( unsigned k = 1 ; k < = 1'000'000'000 ; k * = 10 ) {
T result = " test = " _ss + k + " times " ;
# ifdef CHECK_RESULT
if ( ! result . starts_with ( " test = " ) | | ! result . ends_with ( " times " ) ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( k ) ;
}
}
}
BENCHMARK ( __ ) - > Name ( " -- Append text, number, text -- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( AppendStreamStrNumStr ) - > Name ( " std::stringstream str; str << \" test = \" << k << \" times \" ; " ) ;
BENCHMARK ( AppendStdStringStrNumStr ) - > Name ( " std::string str = \" test = \" + std::to_string(k) + \" times \" ; " ) ;
BENCHMARK ( AppendSprintfStrNumStr ) - > Name ( " char buf[100]; sprintf(buf, \" test = %u times \" , k); std::string str = buf; " ) ;
BENCHMARK ( AppendFormatStrNumStr ) - > Name ( " std::string str = std::format( \" test = {} times \" , k); " ) ;
BENCHMARK ( AppendSimStrStrNumStrF < lstringa < 8 > > ) - > Name ( " lstringa<8> str; str.format( \" test = {} times \" , k); " ) ;
BENCHMARK ( AppendSimStrStrNumStrF < lstringa < 32 > > ) - > Name ( " lstringa<32> str; str.format( \" test = {} times \" , k); " ) ;
BENCHMARK ( AppendSimStrStrNumStr < lstringa < 8 > > ) - > Name ( " lstringa<8> str = \" test = \" + k + \" times \" ; " ) ;
BENCHMARK ( AppendSimStrStrNumStr < lstringa < 32 > > ) - > Name ( " lstringa<32> str = \" test = \" + k + \" times \" ; " ) ;
BENCHMARK ( AppendSimStrStrNumStr < stringa > ) - > Name ( " stringa str = \" test = \" + k + \" times \" ; " ) ;
const char NUMBER_LIST [ ] = " 1-!- 2-!- 3-!- 4 -!- 5-!- 6 -!- 7-!- -8-!- 0xaF-!- 15-!- 010 " ; // 218
void SplitConvertIntStdString ( benchmark : : State & state ) {
std : : string numbers = NUMBER_LIST ;
for ( auto _ : state ) {
int total = 0 ;
for ( size_t start = 0 ; start < numbers . length ( ) ; ) {
int delim = numbers . find ( " -!- " , start ) ;
if ( delim = = std : : string : : npos ) {
delim = numbers . size ( ) ;
}
std : : string part = numbers . substr ( start , delim - start ) ;
total + = std : : strtol ( part . c_str ( ) , nullptr , 0 ) ;
start = delim + 3 ;
}
# ifdef CHECK_RESULT
if ( total ! = 218 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( total ) ;
benchmark : : DoNotOptimize ( numbers ) ;
}
}
void SplitConvertIntSimStr ( benchmark : : State & state ) {
stra numbers = NUMBER_LIST ;
for ( auto _ : state ) {
int total = 0 ;
for ( auto splitter = numbers . splitter ( " -!- " ) ; ! splitter . is_done ( ) ; ) {
total + = splitter . next ( ) . as_int < int > ( ) ;
}
# ifdef CHECK_RESULT
if ( total ! = 218 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( total ) ;
benchmark : : DoNotOptimize ( numbers ) ;
}
}
void SplitConvertIntSplitf ( benchmark : : State & state ) {
stra numbers = NUMBER_LIST ;
for ( auto _ : state ) {
int total = 0 ;
numbers . splitf < void > ( " -!- " , [ & ] ( ssa & part ) { total + = part . as_int < int > ( ) ; } ) ;
# ifdef CHECK_RESULT
if ( total ! = 218 ) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( total ) ;
benchmark : : DoNotOptimize ( numbers ) ;
}
}
BENCHMARK ( __ ) - > Name ( " -- Split text and convert to int -- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( SplitConvertIntStdString ) - > Name ( " std::string::find + substr + std::strtol " ) ;
BENCHMARK ( SplitConvertIntSimStr ) - > Name ( " ssa::splitter + ssa::as_int " ) ;
BENCHMARK ( SplitConvertIntSplitf ) - > Name ( " ssa::splitf + functor " ) ;
void ReplaceSymbolsStdStringNaiveWrong ( benchmark : : State & state ) {
std : : string_view source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
;
std : : vector < std : : pair < u8s , std : : string_view > > repl = {
{ ' & ' , " & " } ,
{ ' - ' , " " } ,
{ ' < ' , " < " } ,
{ ' > ' , " > " } ,
{ ' \' ' , " ' " } ,
{ ' \" ' , " " " }
} ;
auto repl_all = [ ] ( std : : string & str , char s , std : : string_view repl ) {
size_t start_pos = 0 ;
while ( ( start_pos = str . find ( s , start_pos ) ) ! = std : : string : : npos ) {
str . replace ( start_pos , 1 , repl ) ;
start_pos + = repl . length ( ) ;
}
} ;
for ( auto _ : state ) {
std : : string result { source } ;
for ( const auto & r : repl ) {
repl_all ( result , r . first , r . second ) ;
}
# ifdef CHECK_RESULT
if ( result
! =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
benchmark : : DoNotOptimize ( repl ) ;
}
}
void ReplaceSymbolsStdStringNaiveRight ( benchmark : : State & state ) {
std : : string_view source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
;
std : : vector < std : : pair < u8s , std : : string_view > > repl = {
{ ' - ' , " " } ,
{ ' < ' , " < " } ,
{ ' > ' , " > " } ,
{ ' \' ' , " ' " } ,
{ ' \" ' , " " " } ,
{ ' & ' , " & " } ,
} ;
for ( auto _ : state ) {
std : : string result { source } ;
std : : string pattern ;
for ( const auto & r : repl ) {
pattern + = r . first ;
}
size_t start_pos = 0 ;
while ( ( start_pos = result . find_first_of ( pattern , start_pos ) ) ! = std : : string : : npos ) {
size_t idx = pattern . find ( result [ start_pos ] ) ;
result . replace ( start_pos , 1 , repl [ idx ] . second ) ;
start_pos + = repl [ idx ] . second . length ( ) ;
}
# ifdef CHECK_RESULT
if ( result
! =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
benchmark : : DoNotOptimize ( repl ) ;
}
}
void ReplaceSymbolsStdString ( benchmark : : State & state ) {
std : : string_view source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
;
2025-11-25 15:55:16 +00:00
2025-04-05 14:21:11 +00:00
const std : : string_view repl_from = " -<>' \" & " ;
const std : : string_view repl_to [ ] = { " " , " < " , " > " , " ' " , " " " , " & " } ;
for ( auto _ : state ) {
std : : string result ;
for ( size_t start = 0 ; start < source . size ( ) ; ) {
size_t idx = source . find_first_of ( repl_from , start ) ;
if ( idx = = std : : string : : npos ) {
result + = source . substr ( start ) ;
break ;
}
if ( idx > start ) {
result + = source . substr ( start , idx - start ) ;
}
size_t what = repl_from . find ( source [ idx ] ) ;
result + = repl_to [ what ] ;
start = idx + 1 ;
}
# ifdef CHECK_RESULT
if ( result
! =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
}
}
template < bool UseVector >
void ReplaceSymbolsDynPatternSimStr ( benchmark : : State & state ) {
stra source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
;
std : : vector < std : : pair < u8s , ssa > > repl = {
{ ' - ' , " " } ,
{ ' < ' , " < " } ,
{ ' > ' , " > " } ,
{ ' \' ' , " ' " } ,
{ ' \" ' , " " " } ,
{ ' & ' , " & " } ,
} ;
for ( auto _ : state ) {
stringa result = expr_replace_symbols < u8s , UseVector > { source , repl } ;
# ifdef CHECK_RESULT
if ( result
! =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
benchmark : : DoNotOptimize ( repl ) ;
}
}
template < bool UseVector >
void ReplaceSymbolsCons2PatternSimStr ( benchmark : : State & state ) {
stra source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf "
;
for ( auto _ : state ) {
stringa result = e_repl_const_symbols < UseVector > ( source ,
' - ' , " " ,
' < ' , " < " ,
' > ' , " > " ,
' \' ' , " ' " ,
' \" ' , " " " ,
' & ' , " & "
) ;
# ifdef CHECK_RESULT
if ( result
! =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
" ksjdfksjd "dkjfsjkhdf dfj ' kdkd "dkfdkfkdjf "
) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
}
}
BENCHMARK ( __ ) - > Name ( " -- Replace symbols in text ~400 symbols -- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( ReplaceSymbolsStdStringNaiveWrong ) - > Name ( " Naive (and wrong) replace symbols with std::string find + replace " ) ;
BENCHMARK ( ReplaceSymbolsStdStringNaiveRight ) - > Name ( " replace symbols with std::string find_first_of + replace " ) ;
BENCHMARK ( ReplaceSymbolsStdString ) - > Name ( " replace symbols with std::string_view find_first_of + copy " ) ;
BENCHMARK ( ReplaceSymbolsDynPatternSimStr < false > ) - > Name ( " replace runtime symbols with string expressions and without remembering all search results " ) ;
BENCHMARK ( ReplaceSymbolsDynPatternSimStr < true > ) - > Name ( " replace runtime symbols with simstr and memorization of all search results " ) ;
BENCHMARK ( ReplaceSymbolsCons2PatternSimStr < false > ) - > Name ( " replace const symbols with string expressions and without remembering all search results " ) ;
BENCHMARK ( ReplaceSymbolsCons2PatternSimStr < true > ) - > Name ( " replace const symbols with string expressions and memorization of all search results " ) ;
void ShortReplaceSymbolsStdStringNaiveWrong ( benchmark : : State & state ) {
std : : string_view source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
;
std : : vector < std : : pair < u8s , std : : string_view > > repl = {
{ ' & ' , " & " } ,
{ ' - ' , " " } ,
{ ' < ' , " < " } ,
{ ' > ' , " > " } ,
{ ' \' ' , " ' " } ,
{ ' \" ' , " " " }
} ;
auto repl_all = [ ] ( std : : string & str , char s , std : : string_view repl ) {
size_t start_pos = 0 ;
while ( ( start_pos = str . find ( s , start_pos ) ) ! = std : : string : : npos ) {
str . replace ( start_pos , 1 , repl ) ;
start_pos + = repl . length ( ) ;
}
} ;
for ( auto _ : state ) {
std : : string result { source } ;
for ( const auto & r : repl ) {
repl_all ( result , r . first , r . second ) ;
}
# ifdef CHECK_RESULT
if ( result
! =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
benchmark : : DoNotOptimize ( repl ) ;
}
}
void ShortReplaceSymbolsStdStringNaiveRight ( benchmark : : State & state ) {
std : : string_view source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
;
std : : vector < std : : pair < u8s , std : : string_view > > repl = {
{ ' - ' , " " } ,
{ ' < ' , " < " } ,
{ ' > ' , " > " } ,
{ ' \' ' , " ' " } ,
{ ' \" ' , " " " } ,
{ ' & ' , " & " } ,
} ;
for ( auto _ : state ) {
std : : string result { source } ;
std : : string pattern ;
for ( const auto & r : repl ) {
pattern + = r . first ;
}
size_t start_pos = 0 ;
while ( ( start_pos = result . find_first_of ( pattern , start_pos ) ) ! = std : : string : : npos ) {
size_t idx = pattern . find ( result [ start_pos ] ) ;
result . replace ( start_pos , 1 , repl [ idx ] . second ) ;
start_pos + = repl [ idx ] . second . length ( ) ;
}
# ifdef CHECK_RESULT
if ( result
! =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
benchmark : : DoNotOptimize ( repl ) ;
}
}
void ShortReplaceSymbolsStdString ( benchmark : : State & state ) {
std : : string_view source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
;
2025-11-25 15:55:16 +00:00
2025-04-05 14:21:11 +00:00
const std : : string_view repl_from = " -<>' \" & " ;
const std : : string_view repl_to [ ] = { " " , " < " , " > " , " ' " , " " " , " & " } ;
for ( auto _ : state ) {
std : : string result ;
for ( size_t start = 0 ; start < source . size ( ) ; ) {
size_t idx = source . find_first_of ( repl_from , start ) ;
if ( idx = = std : : string : : npos ) {
result + = source . substr ( start ) ;
break ;
}
if ( idx > start ) {
result + = source . substr ( start , idx - start ) ;
}
size_t what = repl_from . find_first_of ( source [ idx ] ) ;
result + = repl_to [ what ] ;
start = idx + 1 ;
}
# ifdef CHECK_RESULT
if ( result
! =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
}
}
template < bool UseVector >
void ShortReplaceSymbolsDynPatternSimStr ( benchmark : : State & state ) {
stra source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
;
std : : vector < std : : pair < u8s , ssa > > repl = {
{ ' - ' , " " } ,
{ ' < ' , " < " } ,
{ ' > ' , " > " } ,
{ ' \' ' , " ' " } ,
{ ' \" ' , " " " } ,
{ ' & ' , " & " } ,
} ;
for ( auto _ : state ) {
stringa result = expr_replace_symbols < u8s , UseVector > { source , repl } ;
# ifdef CHECK_RESULT
if ( result
! =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
benchmark : : DoNotOptimize ( repl ) ;
}
}
template < bool UseVector >
void ShortReplaceSymbolsCons2PatternSimStr ( benchmark : : State & state ) {
stra source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
;
for ( auto _ : state ) {
stringa result = e_repl_const_symbols < UseVector > ( source ,
' - ' , " " ,
' < ' , " < " ,
' > ' , " > " ,
' \' ' , " ' " ,
' \" ' , " " " ,
' & ' , " & "
) ;
# ifdef CHECK_RESULT
if ( result
! =
" abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj > "
) {
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
}
}
BENCHMARK ( __ ) - > Name ( " -- Replace symbols in text ~40 symbols -- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( ShortReplaceSymbolsStdStringNaiveWrong ) - > Name ( " Short Naive (and wrong) replace symbols with std::string find + replace " ) ;
BENCHMARK ( ShortReplaceSymbolsStdStringNaiveRight ) - > Name ( " Short replace symbols with std::string find_first_of + replace " ) ;
BENCHMARK ( ShortReplaceSymbolsStdString ) - > Name ( " Short replace symbols with std::string_view find_first_of + copy " ) ;
BENCHMARK ( ShortReplaceSymbolsDynPatternSimStr < false > ) - > Name ( " Short replace runtime symbols with string expressions and without remembering all search results " ) ;
BENCHMARK ( ShortReplaceSymbolsDynPatternSimStr < true > ) - > Name ( " Short replace runtime symbols with simstr and memorization of all search results " ) ;
BENCHMARK ( ShortReplaceSymbolsCons2PatternSimStr < false > ) - > Name ( " Short replace const symbols with string expressions and without remembering all search results " ) ;
BENCHMARK ( ShortReplaceSymbolsCons2PatternSimStr < true > ) - > Name ( " Short replace const symbols with string expressions and memorization of all search results " ) ;
template < size_t Long >
void ReplaceAllLongerStdString ( benchmark : : State & state ) {
std : : string_view source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba " ;
std : : string_view sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a " ;
std : : string_view pattern = " bb " ;
std : : string_view repl = " ---- " ;
std : : string big_source , big_sample ;
for ( int i = 0 ; i < Long ; i + + ) {
big_source + = source ;
big_sample + = sample ;
}
2025-11-25 15:55:16 +00:00
2025-04-05 14:21:11 +00:00
for ( auto _ : state ) {
std : : string result { big_source } ;
size_t start_pos = 0 ;
while ( ( start_pos = result . find ( pattern , start_pos ) ) ! = std : : string : : npos ) {
result . replace ( start_pos , pattern . length ( ) , repl ) ;
start_pos + = repl . length ( ) ;
}
# ifdef CHECK_RESULT
if ( result ! = big_sample ) {
state . SkipWithError ( " error in replace " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
benchmark : : DoNotOptimize ( pattern ) ;
benchmark : : DoNotOptimize ( repl ) ;
}
}
template < size_t N , size_t Count >
void ReplaceAllLongerSimString ( benchmark : : State & state ) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba " ;
ssa sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a " ;
2025-11-25 15:55:16 +00:00
2025-04-05 14:21:11 +00:00
lstringa < 2048 > big_source { Count , source } , big_sample { Count , sample } ;
for ( auto _ : state ) {
lstringa < N > result = big_source ;
result . replace ( " bb " , " ---- " ) ;
# ifdef CHECK_RESULT
if ( result . to_str ( ) ! = big_sample ) {
std : : cout < < result . length ( ) < < " : " < < result < < " \n \n " < < big_sample . length ( ) < < " : " < < big_sample < < " \n \n " ;
state . SkipWithError ( " error in replace " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
}
}
template < size_t Count >
void ReplaceAllLongerSimStringExpr ( benchmark : : State & state ) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba " ;
ssa sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a " ;
2025-11-25 15:55:16 +00:00
2025-04-05 14:21:11 +00:00
lstringa < 2048 > big_source { Count , source } , big_sample { Count , sample } ;
for ( auto _ : state ) {
2026-02-14 10:09:54 +00:00
stringa result = e_repl ( big_source , " bb " , " ---- " ) ;
2025-04-05 14:21:11 +00:00
# ifdef CHECK_RESULT
if ( result . to_str ( ) ! = big_sample ) {
std : : cout < < result . length ( ) < < " : " < < result < < " \n \n " < < big_sample . length ( ) < < " : " < < big_sample < < " \n \n " ;
state . SkipWithError ( " error in replace " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
}
}
template < size_t Long >
void ReplaceAllEqualStdString ( benchmark : : State & state ) {
std : : string_view source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba " ;
std : : string_view sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a " ;
std : : string_view pattern = " bb " ;
std : : string_view repl = " -- " ;
std : : string big_source , big_sample ;
for ( int i = 0 ; i < Long ; i + + ) {
big_source + = source ;
big_sample + = sample ;
}
for ( auto _ : state ) {
std : : string result { big_source } ;
size_t start_pos = 0 ;
while ( ( start_pos = result . find ( pattern , start_pos ) ) ! = std : : string : : npos ) {
result . replace ( start_pos , pattern . length ( ) , repl ) ;
start_pos + = repl . length ( ) ;
}
# ifdef CHECK_RESULT
if ( result ! = big_sample ) {
state . SkipWithError ( " error in replace " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
benchmark : : DoNotOptimize ( pattern ) ;
benchmark : : DoNotOptimize ( repl ) ;
}
}
template < size_t N , size_t Long >
void ReplaceAllEqualSimString ( benchmark : : State & state ) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba " ;
ssa sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a " ;
lstringa < 2048 > big_source { Long , source } , big_sample { Long , sample } ;
for ( auto _ : state ) {
lstringa < N > result = big_source ;
result . replace ( " bb " , " -- " ) ;
# ifdef CHECK_RESULT
if ( result . to_str ( ) ! = big_sample ) {
std : : cout < < result . length ( ) < < " : " < < result < < " \n \n " < < big_sample . length ( ) < < " : " < < big_sample < < " \n \n " ;
state . SkipWithError ( " error in replace " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
}
}
template < size_t Count >
void ReplaceAllEqualSimStringExpr ( benchmark : : State & state ) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba " ;
ssa sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a " ;
ssa pattern = " bb " ;
ssa repl = " -- " ;
2025-11-25 15:55:16 +00:00
2025-04-05 14:21:11 +00:00
lstringa < 2048 > big_source { Count , source } , big_sample { Count , sample } ;
for ( auto _ : state ) {
stringa result = e_repl ( big_source . to_str ( ) , " bb " , " -- " ) ;
# ifdef CHECK_RESULT
if ( result . to_str ( ) ! = big_sample ) {
std : : cout < < result . length ( ) < < " : " < < result < < " \n \n " < < big_sample . length ( ) < < " : " < < big_sample < < " \n \n " ;
state . SkipWithError ( " error in replace " ) ;
break ;
}
# endif
benchmark : : DoNotOptimize ( result ) ;
benchmark : : DoNotOptimize ( source ) ;
benchmark : : DoNotOptimize ( pattern ) ;
benchmark : : DoNotOptimize ( repl ) ;
}
}
BENCHMARK ( __ ) - > Name ( " ----- Replace All Str To Longer Size --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( ReplaceAllLongerStdString < 1 > ) - > Name ( " replace bb to ---- in std::string|64 " ) ;
BENCHMARK ( ReplaceAllLongerStdString < 4 > ) - > Name ( " replace bb to ---- in std::string|256 " ) ;
BENCHMARK ( ReplaceAllLongerStdString < 8 > ) - > Name ( " replace bb to ---- in std::string|512 " ) ;
BENCHMARK ( ReplaceAllLongerStdString < 16 > ) - > Name ( " replace bb to ---- in std::string|1024 " ) ;
BENCHMARK ( ReplaceAllLongerStdString < 32 > ) - > Name ( " replace bb to ---- in std::string|2048 " ) ;
BENCHMARK ( ReplaceAllLongerSimString < 8 , 1 > ) - > Name ( " replace bb to ---- in lstringa<8>|64 " ) ;
BENCHMARK ( ReplaceAllLongerSimString < 8 , 4 > ) - > Name ( " replace bb to ---- in lstringa<8>|256 " ) ;
BENCHMARK ( ReplaceAllLongerSimString < 8 , 8 > ) - > Name ( " replace bb to ---- in lstringa<8>|512 " ) ;
BENCHMARK ( ReplaceAllLongerSimString < 8 , 16 > ) - > Name ( " replace bb to ---- in lstringa<8>|1024 " ) ;
BENCHMARK ( ReplaceAllLongerSimString < 8 , 32 > ) - > Name ( " replace bb to ---- in lstringa<8>|2048 " ) ;
BENCHMARK ( ReplaceAllLongerSimStringExpr < 1 > ) - > Name ( " replace bb to ---- by init stringa|64 " ) ;
BENCHMARK ( ReplaceAllLongerSimStringExpr < 4 > ) - > Name ( " replace bb to ---- by init stringa|256 " ) ;
BENCHMARK ( ReplaceAllLongerSimStringExpr < 8 > ) - > Name ( " replace bb to ---- by init stringa|512 " ) ;
BENCHMARK ( ReplaceAllLongerSimStringExpr < 16 > ) - > Name ( " replace bb to ---- by init stringa|1024 " ) ;
BENCHMARK ( ReplaceAllLongerSimStringExpr < 32 > ) - > Name ( " replace bb to ---- by init stringa|2048 " ) ;
BENCHMARK ( __ ) - > Name ( " ----- Replace All Str To Same Size --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( ReplaceAllEqualStdString < 1 > ) - > Name ( " replace bb to -- in std::string|64 " ) ;
BENCHMARK ( ReplaceAllEqualStdString < 4 > ) - > Name ( " replace bb to -- in std::string|256 " ) ;
BENCHMARK ( ReplaceAllEqualStdString < 8 > ) - > Name ( " replace bb to -- in std::string|512 " ) ;
BENCHMARK ( ReplaceAllEqualStdString < 16 > ) - > Name ( " replace bb to -- in std::string|1024 " ) ;
BENCHMARK ( ReplaceAllEqualStdString < 32 > ) - > Name ( " replace bb to -- in std::string|2048 " ) ;
BENCHMARK ( ReplaceAllEqualSimString < 8 , 1 > ) - > Name ( " replace bb to -- in lstringa<8>|64 " ) ;
BENCHMARK ( ReplaceAllEqualSimString < 8 , 4 > ) - > Name ( " replace bb to -- in lstringa<8>|256 " ) ;
BENCHMARK ( ReplaceAllEqualSimString < 8 , 8 > ) - > Name ( " replace bb to -- in lstringa<8>|512 " ) ;
BENCHMARK ( ReplaceAllEqualSimString < 8 , 16 > ) - > Name ( " replace bb to -- in lstringa<8>|1024 " ) ;
BENCHMARK ( ReplaceAllEqualSimString < 8 , 32 > ) - > Name ( " replace bb to -- in lstringa<8>|2048 " ) ;
BENCHMARK ( ReplaceAllEqualSimStringExpr < 1 > ) - > Name ( " replace bb to -- by init stringa|64 " ) ;
BENCHMARK ( ReplaceAllEqualSimStringExpr < 4 > ) - > Name ( " replace bb to -- by init stringa|256 " ) ;
BENCHMARK ( ReplaceAllEqualSimStringExpr < 8 > ) - > Name ( " replace bb to -- by init stringa|512 " ) ;
BENCHMARK ( ReplaceAllEqualSimStringExpr < 16 > ) - > Name ( " replace bb to -- by init stringa|1024 " ) ;
BENCHMARK ( ReplaceAllEqualSimStringExpr < 32 > ) - > Name ( " replace bb to -- by init stringa|2048 " ) ;
std : : vector < stringa > prepareTestStrings ( size_t length , size_t delta , size_t count ) {
std : : vector < stringa > result ;
result . reserve ( count ) ;
struct expr_rand {
using symb_type = u8s ;
size_t len ;
size_t length ( ) const noexcept {
return len ;
}
char * place ( char * ptr ) const {
for ( size_t idx = len ; idx > 0 ; idx - - ) {
* ptr + + = char ( ' ' + std : : rand ( ) % 200 ) ;
}
return ptr ;
}
} ;
for ( size_t idx = 0 ; idx < count ; idx + + ) {
result . emplace_back ( expr_rand { length + std : : rand ( ) % delta } ) ;
}
return result ;
}
std : : vector < stringa > bs_sim = prepareTestStrings ( 30 , 20 , 10'000 ) ;
std : : vector < std : : string > prepareTestStdStrings ( ) {
std : : vector < std : : string > result ;
result . reserve ( bs_sim . size ( ) ) ;
for ( const auto & s : bs_sim ) {
result . emplace_back ( s . to_string ( ) ) ;
}
return result ;
}
std : : vector < std : : string > bs_std = prepareTestStdStrings ( ) ;
void HashMapSimStr ( benchmark : : State & state ) {
for ( auto _ : state ) {
hashStrMapA < size_t > store ;
for ( size_t idx = 0 ; idx < bs_sim . size ( ) ; idx + + ) {
store . try_emplace ( bs_sim [ idx ] , idx ) ;
}
# ifdef CHECK_RESULT
if ( store . size ( ) ! = bs_sim . size ( ) ) {
state . SkipWithError ( " bad inserts " ) ;
}
# endif
for ( size_t idx = 0 ; idx < bs_sim . size ( ) ; idx + + ) {
auto find = store . find ( bs_sim [ idx ] ) ;
size_t res = find - > second ;
# ifdef CHECK_RESULT
if ( res ! = idx ) {
state . SkipWithError ( " bad find " ) ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
}
}
}
void HashMapStdStr ( benchmark : : State & state ) {
for ( auto _ : state ) {
std : : unordered_map < std : : string , size_t > store ;
for ( size_t idx = 0 ; idx < bs_std . size ( ) ; idx + + ) {
store . try_emplace ( bs_std [ idx ] , idx ) ;
}
# ifdef CHECK_RESULT
if ( store . size ( ) ! = bs_std . size ( ) ) {
state . SkipWithError ( " bad inserts " ) ;
}
# endif
for ( size_t idx = 0 ; idx < bs_std . size ( ) ; idx + + ) {
auto find = store . find ( bs_std [ idx ] ) ;
size_t res = find - > second ;
# ifdef CHECK_RESULT
if ( res ! = idx ) {
state . SkipWithError ( " bad find " ) ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
}
}
}
void HashMapSimSsa ( benchmark : : State & state ) {
for ( auto _ : state ) {
hashStrMapA < size_t > store ;
for ( size_t idx = 0 ; idx < bs_sim . size ( ) ; idx + + ) {
store . emplace ( bs_sim [ idx ] , idx ) ;
}
# ifdef CHECK_RESULT
if ( store . size ( ) ! = bs_sim . size ( ) ) {
state . SkipWithError ( " bad inserts " ) ;
}
# endif
for ( size_t idx = 0 ; idx < bs_sim . size ( ) ; idx + + ) {
ssa key = bs_sim [ idx ] ;
auto find = store . find ( key ) ;
size_t res = find - > second ;
# ifdef CHECK_RESULT
if ( res ! = idx ) {
state . SkipWithError ( " bad find " ) ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
}
}
}
void HashMapStdStrView ( benchmark : : State & state ) {
for ( auto _ : state ) {
std : : unordered_map < std : : string , size_t > store ;
for ( size_t idx = 0 ; idx < bs_std . size ( ) ; idx + + ) {
store . emplace ( bs_std [ idx ] , idx ) ;
}
# ifdef CHECK_RESULT
if ( store . size ( ) ! = bs_std . size ( ) ) {
state . SkipWithError ( " bad inserts " ) ;
}
# endif
for ( size_t idx = 0 ; idx < bs_std . size ( ) ; idx + + ) {
std : : string_view key = bs_std [ idx ] ;
auto find = store . find ( std : : string { key } ) ;
size_t res = find - > second ;
# ifdef CHECK_RESULT
if ( res ! = idx ) {
state . SkipWithError ( " bad find " ) ;
}
# endif
benchmark : : DoNotOptimize ( res ) ;
}
}
}
BENCHMARK ( __ ) - > Name ( " ----- Hash Map insert and find --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( HashMapSimStr ) - > Name ( " hashStrMapA<size_t> emplace & find stringa; " ) ;
BENCHMARK ( HashMapStdStr ) - > Name ( " std::unordered_map<std::string, size_t> emplace & find std::string; " ) ;
BENCHMARK ( HashMapSimSsa ) - > Name ( " hashStrMapA<size_t> emplace & find ssa; " ) ;
BENCHMARK ( HashMapStdStrView ) - > Name ( " std::unordered_map<std::string, size_t> emplace & find std::string_view; " ) ;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Н а б о р тестов, имитирующий довольно типовой сценарий, похож на то, что встречалось в работе
// По имеющимся данным о неких функциях и их параметрах - построить полное имя функции
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum class Types {
int2 ,
int4 ,
int8 ,
bytea ,
text ,
char_ ,
varchar ,
boolean ,
last ,
} ;
const ssa type_names [ ] = {
" int2 " ,
" int4 " ,
" int8 " ,
" bytea " ,
" text " ,
" char " ,
" varchar " ,
" boolean "
} ;
const std : : string_view type_names_sv [ ] = {
" int2 " ,
" int4 " ,
" int8 " ,
" bytea " ,
" text " ,
" char " ,
" varchar " ,
" boolean "
} ;
constexpr bool is_power_of_two_or_zero ( uint32_t value ) {
return ! ( value & ( value - 1 ) ) ;
}
struct type_set {
uint32_t value ;
void to_simstr ( mutable_str < u8s > auto & str ) const {
if ( ! value ) {
str + = " {?} " ;
} else if ( value = = 0xFFFFFFFF ) {
str + = " any " ;
} else {
if ( ! is_power_of_two_or_zero ( value ) ) {
str + = " { " ;
}
bool add_comma = false ;
for ( unsigned idx = 0 ; idx < ( unsigned ) Types : : last ; idx + + ) {
if ( value & ( 1 < < idx ) ) {
str + = e_if ( add_comma , " , " ) + type_names [ idx ] ;
add_comma = true ;
}
}
if ( ! is_power_of_two_or_zero ( value ) ) {
str + = " } " ;
}
}
}
auto get_simstr ( ) const {
lstringa < 128 > str ;
if ( ! value ) {
str = " {?} " ;
} else if ( value = = 0xFFFFFFFF ) {
str = " any " ;
} else {
if ( ! is_power_of_two_or_zero ( value ) ) {
str = " { " ;
}
bool add_comma = false ;
for ( unsigned idx = 0 ; idx < ( unsigned ) Types : : last ; idx + + ) {
if ( value & ( 1 < < idx ) ) {
str + = e_if ( add_comma , " , " ) + type_names [ idx ] ;
add_comma = true ;
}
}
if ( ! is_power_of_two_or_zero ( value ) ) {
str + = " } " ;
}
}
2025-11-25 15:55:16 +00:00
return str ;
2025-04-05 14:21:11 +00:00
}
void to_stdstr ( std : : string & str ) const {
if ( ! value ) {
str + = " {?} " ;
} else if ( value = = 0xFFFFFFFF ) {
str + = " any " ;
} else {
if ( ! is_power_of_two_or_zero ( value ) ) {
str + = " { " ;
}
bool add_comma = false ;
for ( unsigned idx = 0 ; idx < ( unsigned ) Types : : last ; idx + + ) {
if ( value & ( 1 < < idx ) ) {
if ( add_comma ) {
str + = " , " ;
}
str + = type_names_sv [ idx ] ;
add_comma = true ;
}
}
if ( ! is_power_of_two_or_zero ( value ) ) {
str + = " } " ;
}
}
}
void to_stream ( std : : ostream & str ) const {
if ( ! value ) {
str < < " {?} " ;
} else if ( value = = 0xFFFFFFFF ) {
str < < " any " ;
} else {
if ( ! is_power_of_two_or_zero ( value ) ) {
str < < " { " ;
}
bool add_comma = false ;
for ( unsigned idx = 0 ; idx < ( unsigned ) Types : : last ; idx + + ) {
if ( value & ( 1 < < idx ) ) {
if ( add_comma ) {
str < < " , " ;
}
str < < type_names_sv [ idx ] ;
add_comma = true ;
}
}
if ( ! is_power_of_two_or_zero ( value ) ) {
str < < " } " ;
}
}
}
} ;
struct param {
type_set allowed_types ;
bool optional ;
} ;
struct function {
stringa name ;
std : : string std_name ;
std : : vector < param > params ;
Types ret_type ;
bool has_ret_type_resolver ;
bool unlim_params ;
// Построение полного имени с помощью simstr строковых объектов и выражений
stringa build_full_name ( ) const {
lstringa < 512 > str = e_choice ( has_ret_type_resolver , " any " , type_names [ ( unsigned ) ret_type ] ) + " " + name + " ( " ;
bool add_comma = false ;
for ( const auto & param : params ) {
str + = e_if ( add_comma , " , " ) + e_if ( param . optional , " [ " ) ;
param . allowed_types . to_simstr ( str ) ;
if ( param . optional ) {
str + = " ] " ;
}
add_comma = true ;
}
return str + e_if ( unlim_params , e_if ( add_comma , " , " ) + " ... " ) + " ) " ;
}
stringa build_full_name1 ( ) const {
lstringa < 512 > str = e_choice ( has_ret_type_resolver , " any " , type_names [ ( unsigned ) ret_type ] ) + " " + name + " ( " ;
bool add_comma = false ;
for ( const auto & param : params ) {
str + = e_if ( add_comma , " , " ) + e_if ( param . optional , " [ " ) + param . allowed_types . get_simstr ( ) + e_if ( param . optional , " ] " ) ;
add_comma = true ;
}
return str + e_if ( unlim_params , e_if ( add_comma , " , " ) + " ... " ) + " ) " ;
}
// Построение полного имени с помощью std::string
std : : string build_full_name_std ( ) const {
std : : string str { has_ret_type_resolver ? " any " sv : type_names_sv [ ( unsigned ) ret_type ] } ;
str + = " " ;
str + = std_name ;
str + = " ( " ;
bool add_comma = false ;
for ( const auto & param : params ) {
if ( add_comma ) {
str + = " , " ;
}
if ( param . optional ) {
str + = " [ " ;
}
param . allowed_types . to_stdstr ( str ) ;
if ( param . optional ) {
str + = " ] " ;
}
add_comma = true ;
}
if ( unlim_params ) {
if ( add_comma ) {
str + = " , " ;
}
str + = " ... " ;
}
str + = " ) " ;
//std::cout << "Len=" << str.length() << ", Cap=" << str.capacity() << "\n";
return str ;
}
// Построение полного имени с помощью std::string
std : : string build_full_name_std1 ( ) const {
std : : string str { has_ret_type_resolver ? " any " sv : type_names_sv [ ( unsigned ) ret_type ] } ;
str + = " " + std_name + " ( " ;
bool add_comma = false ;
for ( const auto & param : params ) {
if ( add_comma ) {
str + = " , " ;
}
if ( param . optional ) {
str + = " [ " ;
}
param . allowed_types . to_stdstr ( str ) ;
if ( param . optional ) {
str + = " ] " ;
}
add_comma = true ;
}
if ( unlim_params ) {
if ( add_comma ) {
str + = " , " ;
}
str + = " ... " ;
}
str + = " ) " ;
//std::cout << "Len=" << str.length() << ", Cap=" << str.capacity() << "\n";
return str ;
}
// Построение полного имени с помощью std::ostringstream
std : : string build_full_name_stream ( ) const {
std : : ostringstream str ;
if ( has_ret_type_resolver ) {
str < < " any " ;
} else {
str < < type_names_sv [ ( unsigned ) ret_type ] ;
}
str < < " " < < std_name < < " ( " ;
bool add_comma = false ;
for ( const auto & param : params ) {
if ( add_comma ) {
str < < " , " ;
}
if ( param . optional ) {
str < < " [ " ;
}
param . allowed_types . to_stream ( str ) ;
if ( param . optional ) {
str < < " ] " ;
}
add_comma = true ;
}
if ( unlim_params ) {
if ( add_comma ) {
str < < " , " ;
}
str < < " ... " ;
}
str < < " ) " ;
return str . str ( ) ;
}
} ;
// Тестовые варианты функций
const struct {
function f ;
std : : string_view check ;
} functions [ ] = {
{ { " func1 " , " func1 " , { } , Types : : boolean , true , true } , " any func1(...) " } ,
{ { " function2 " , " function2 " , { { 4 , false } , { 12 , true } } , Types : : int2 , false , false } , " int2 function2(int8, [{int8, bytea}]) " } ,
{ { " func3 " , " func3 " , { { 16 , false } , { 7 , false } , { 32 , true } } , Types : : char_ , false , true } , " char func3(text, {int2, int4, int8}, [char], ...) " } ,
{ { " function4 " , " function4 " , { { 10 , false } , { 64 , false } , { 31 , true } } , Types : : char_ , true , false } , " any function4({int4, bytea}, varchar, [{int2, int4, int8, bytea, text}]) " } ,
{ { " f5 " , " f5 " , { { 10 , false } , { 64 , false } , { 0xFFFFFFFF , false } } , Types : : text , false , true } , " text f5({int4, bytea}, varchar, any, ...) " } ,
} ;
// Замеры скорости выполнения разных вариантов
//> stringa build_full_name() const {
void BuildFuncNameSimStr ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( const auto & f : functions ) {
stringa res = f . f . build_full_name ( ) ;
benchmark : : DoNotOptimize ( res ) ;
# ifdef CHECK_RESULT
2026-01-21 11:59:17 +00:00
if ( res ! = ssa { f . check } ) {
2025-04-05 14:21:11 +00:00
std : : cout < < res < < " \n " ;
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
}
}
}
//> stringa build_full_name1() const {
void BuildFuncNameSimStr1 ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( const auto & f : functions ) {
stringa res = f . f . build_full_name1 ( ) ;
benchmark : : DoNotOptimize ( res ) ;
# ifdef CHECK_RESULT
2026-01-21 11:59:17 +00:00
if ( res ! = ssa { f . check } ) {
2025-04-05 14:21:11 +00:00
std : : cout < < res < < " \n " ;
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
}
}
}
//> std::string build_full_name_std() const {
void BuildFuncNameStdStr ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( const auto & f : functions ) {
std : : string res = f . f . build_full_name_std ( ) ;
benchmark : : DoNotOptimize ( res ) ;
# ifdef CHECK_RESULT
if ( res ! = f . check ) {
std : : cout < < res < < " \n " ;
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
}
}
}
//> std::string build_full_name_std1() const {
void BuildFuncNameStdStr1 ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( const auto & f : functions ) {
std : : string res = f . f . build_full_name_std1 ( ) ;
benchmark : : DoNotOptimize ( res ) ;
# ifdef CHECK_RESULT
if ( res ! = f . check ) {
std : : cout < < res < < " \n " ;
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
}
}
}
//> std::string build_full_name_stream() const {
void BuildFuncNameStream ( benchmark : : State & state ) {
for ( auto _ : state ) {
for ( const auto & f : functions ) {
std : : string res = f . f . build_full_name_stream ( ) ;
benchmark : : DoNotOptimize ( res ) ;
# ifdef CHECK_RESULT
if ( res ! = f . check ) {
std : : cout < < res < < " \n " ;
state . SkipWithError ( " not equal " ) ;
break ;
}
# endif
}
}
}
BENCHMARK ( __ ) - > Name ( " ----- Build Full Func Name --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( BuildFuncNameStdStr ) - > Name ( " Build func full name std::string; " ) ;
BENCHMARK ( BuildFuncNameStdStr1 ) - > Name ( " Build func full name std::string 1; " ) ;
BENCHMARK ( BuildFuncNameStream ) - > Name ( " Build func full name std::stream; " ) ;
BENCHMARK ( BuildFuncNameSimStr ) - > Name ( " Build func full name stringa; " ) ;
BENCHMARK ( BuildFuncNameSimStr1 ) - > Name ( " Build func full name stringa 1; " ) ;
2025-11-13 14:57:42 +00:00
2026-02-15 14:13:54 +00:00
void UpperCaseStd ( benchmark : : State & state ) {
static const auto & loc = std : : locale ( " en_US.utf8 " ) ;
for ( auto _ : state ) {
std : : wstring test = L " TestПр иве тTest " ;
benchmark : : DoNotOptimize ( test ) ;
std : : transform ( test . begin ( ) , test . end ( ) , test . begin ( ) , [ ] ( wchar_t s ) {
return std : : toupper ( s , loc ) ;
} ) ;
benchmark : : DoNotOptimize ( test ) ;
# ifdef CHECK_RESULT
if ( test ! = L " TESTПР ИВ Е Т TEST " ) {
state . SkipWithError ( " Bad upper case " ) ;
}
# endif
}
}
void UpperCaseSim ( benchmark : : State & state ) {
for ( auto _ : state ) {
lstringw < 15 > test = L " TestПр иве тTest " ;
benchmark : : DoNotOptimize ( test ) ;
test . upper ( ) ;
benchmark : : DoNotOptimize ( test ) ;
# ifdef CHECK_RESULT
if ( test ! = L " TESTПР ИВ Е Т TEST " ) {
state . SkipWithError ( " Bad upper case " ) ;
}
# endif
}
}
BENCHMARK ( __ ) - > Name ( " ----- Make Upper --------- " ) - > Repetitions ( 1 ) ;
BENCHMARK ( UpperCaseStd ) - > Name ( " To upper case std::wstring " ) ;
BENCHMARK ( UpperCaseSim ) - > Name ( " To upper case lstringw<15> " ) ;
2025-11-13 14:57:42 +00:00
int main ( int argc , char * * argv ) {
2026-02-03 07:38:21 +00:00
std : : cout < < " Benchmarks of simstr, version " SIMSTR_VERSION < < " \n "
< < " Sources: https://github.com/orefkov/simstr \n "
2026-02-27 20:05:49 +00:00
< < " Results: https://orefkov.github.io/simstr/results.html \n "
< < " Compiler " < < CXX_COMPILER_ID < < " " < < CXX_COMPILER_VERSION
# ifdef _LIBCPP_VERSION
< < " , use libc++ "
# endif
< < std : : endl ;
2026-02-08 11:17:03 +00:00
# ifdef EMSCRIPTEN
EM_ASM ( { console . log ( navigator . userAgent ) ; } ) ;
2026-02-12 16:47:32 +00:00
if ( argc = = 2 & & stra { argv [ 1 ] } = = " -sync " ) {
do_sync = true ;
argc = 1 ;
}
2026-02-08 11:17:03 +00:00
# endif
2026-02-03 07:38:21 +00:00
char arg1 [ ] = " --benchmark_repetitions=4 " , arg2 [ ] = " --benchmark_report_aggregates_only=true " ;
2025-11-13 14:57:42 +00:00
char * my_params [ ] = { argv [ 0 ] , arg1 , arg2 } ;
if ( argc < 2 ) {
argc = 3 ;
argv = my_params ;
}
: : benchmark : : Initialize ( & argc , argv ) ;
if ( : : benchmark : : ReportUnrecognizedArguments ( argc , argv ) )
return 1 ;
: : benchmark : : RunSpecifiedBenchmarks ( ) ;
: : benchmark : : Shutdown ( ) ;
2026-02-08 11:17:03 +00:00
# ifdef EMSCRIPTEN
2026-02-10 20:35:02 +00:00
std : : cout < < " Done! \n " ;
2026-02-08 11:17:03 +00:00
EM_ASM ( { on_done ( ) ; } ) ;
# endif
2026-02-10 20:35:02 +00:00
2025-11-13 14:57:42 +00:00
return 0 ;
}