simstr/bench/results.html

4428 lines
311 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<html>
<head>
<meta charset="UTF-8" />
<link href="results.css" rel="stylesheet" />
<title>SimStr benchmarks results</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
let bench_sets = {};
let activeBuilder = buildTestsByPlatformsBar;
let buildAsLine = {
"Copy not literal Str with N symbols": "Length of the copied string",
"Replace All Str To Longer Size": "Length of the string to be replaced",
"Replace All Str To Same Size": "Length of the string to be replaced"
};
function hl() {
document.querySelectorAll('.tooltiptext.code').forEach((el) => {
hljs.highlightElement(el);
});
}
function addBarChart(id, data) {
let canvas = document.getElementById('chart' + id);
new Chart(canvas, {
type: 'bar',
data: data,
options: {
scales: {
y: {
beginAtZero: true
},
x: {
title: {
text: "Time (ns)",
display: true
}
}
},
indexAxis: 'y',
plugins: {
legend: {
position: 'right',
labels: {
font: {
family: "'Cascadia Code', Consolas, 'Courier New', Courier, monospace"
}
}
}
}
}
});
}
function platformChecked(idx) {
return document.getElementById('pl' + idx).checked;
}
function buildPlatformsByTestsBar(bsName) {
if (buildAsLine[bsName]) {
buildPlatformsByTestsLine(bsName, buildAsLine[bsName]);
return;
}
let data = { labels: [], datasets: [] };
for (const i in platform_names) {
if (platformChecked(i))
data.datasets.push({ label: platform_names[i], data: [], borderWidth: 1 });
}
let bs = bench_sets[bsName];
for (const test of bs.tests) {
data.labels.push(test.name);
let ds = 0;
for (const i in test.data) {
if (platformChecked(i)) {
data.datasets[ds++].data.push(test.data[i]);
}
}
}
addBarChart(bs.id, data);
}
function buildTestsByPlatformsBar(bsName) {
if (buildAsLine[bsName], buildAsLine[bsName]) {
buildTestsByPlatformsLine(bsName, buildAsLine[bsName]);
return;
}
let data = { labels: [], datasets: [] };
let bs = bench_sets[bsName];
for (const test of bs.tests) {
data.datasets.push({ label: test.name, data: [], borderWidth: 1 });
}
for (const i in platform_names) {
if (platformChecked(i)) {
data.labels.push(platform_names[i]);
for (const j in bs.tests) {
data.datasets[j].data.push(bs.tests[j].data[i]);
}
}
}
addBarChart(bs.id, data);
}
function buildCanvas(plCount) {
document.querySelectorAll("canvas.bench_chart").forEach(e => e.remove());
for (var bs_name in bench_sets) {
let bs = bench_sets[bs_name];
if (plCount) {
let canvas = document.createElement('canvas');
canvas.id = "chart" + bs.id;
canvas.classList.add('bench_chart');
let h = 20 * plCount * bs.tests.length;
canvas.style.width = "100%";
canvas.style.height = h + "px";
canvas.height = h * devicePixelRatio;
document.getElementById(bs.id).after(canvas);
}
}
}
function addLineChart(canvas, data, title, scaleTitle) {
new Chart(canvas, {
type: 'line',
data: data,
options: {
scales: {
y: {
beginAtZero: true,
title: {
text: scaleTitle,
display: true
}
},
x: {
title: {
text: "Time (ns)",
display: true
}
}
},
indexAxis: 'y',
plugins: {
title: {
display: true,
text: title,
},
legend: {
position: 'right',
labels: {
font: {
family: "'Cascadia Code', Consolas, 'Courier New', Courier, monospace"
}
}
}
}
}
});
}
function buildTestsByPlatformsLineOne(bs, canvas, plIdx, scaleTitle) {
let data = { datasets: [] };
let prevTest = '';
let curData = undefined;
for (const test of bs.tests) {
let m = test.name.match(/(.+)[\/\|](\d+)$/);
if (m[1] != prevTest) {
prevTest = m[1];
curData = { label: prevTest, data: [], borderWidth: 1 };
data.datasets.push(curData);
}
curData.data.push([test.data[plIdx], m[2]]);
}
addLineChart(canvas, data, platform_names[plIdx], scaleTitle);
}
function buildTestsByPlatformsLine(bsName, scaleTitle) {
let bs = bench_sets[bsName];
let canvas = document.getElementById('chart' + bs.id);
let after = null;
for (const i in platform_names) {
if (platformChecked(i)) {
if (!canvas) {
canvas = document.createElement('canvas');
canvas.classList.add('bench_chart');
canvas.style.width = "100%";
after.after(canvas);
}
canvas.style.height = "300px";
canvas.height = 300 * devicePixelRatio;
buildTestsByPlatformsLineOne(bs, canvas, i, scaleTitle);
after = canvas;
canvas = null;
}
}
}
function buildPlatformsByTestsLineOne(bs, canvas, after, testData, title, scaleTitle) {
let data = { datasets: [] };
for (const i in platform_names) {
if (platformChecked(i)) {
ds = {label: platform_names[i], data: []};
for (const test of testData) {
ds.data.push([test.data[i], test.count]);
}
data.datasets.push(ds);
}
}
if (!canvas) {
canvas = document.createElement('canvas');
canvas.classList.add('bench_chart');
canvas.style.width = "100%";
after.after(canvas);
}
canvas.style.height = "300px";
canvas.height = 300 * devicePixelRatio;
addLineChart(canvas, data, title, scaleTitle);
return canvas;
}
function buildPlatformsByTestsLine(bsName, scaleTitle) {
let bs = bench_sets[bsName];
let canvas = document.getElementById('chart' + bs.id);
let after = null;
let data = [];
let prevTest = '';
for (const test of bs.tests) {
let m = test.name.match(/(.+)[\/\|](\d+)$/);
if (m[1] != prevTest) {
if (data.length) {
after = buildPlatformsByTestsLineOne(bs, canvas, after, data, prevTest, scaleTitle);
canvas = null;
}
prevTest = m[1];
data = [];
}
data.push({count: m[2], data: test.data});
}
if (data.length) {
buildPlatformsByTestsLineOne(bs, canvas, after, data, prevTest, scaleTitle);
}
}
function buildCharts() {
let plCount = 0;
for (const i in platform_names) {
if (platformChecked(i))
plCount++;
}
buildCanvas(plCount);
for (var bs_name in bench_sets) {
activeBuilder(bs_name);
}
}
function switchGrouping() {
activeBuilder = document.getElementById('gbp').checked ? buildTestsByPlatformsBar : buildPlatformsByTestsBar;
buildCharts();
}
document.addEventListener('DOMContentLoaded', (event) => {
if (!hljs) {
let scriptTag = document.createElement('script');
scriptTag.src = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js";
scriptTag.onload = hl;
scriptTag.onreadystatechange = hl;
document.body.appendChild(scriptTag);
} else {
hl();
}
if (!Chart) {
let scriptTag = document.createElement('script');
scriptTag.src = "https://cdn.jsdelivr.net/npm/chart.js";
scriptTag.onload = buildCharts;
scriptTag.onreadystatechange = buildCharts;
document.body.appendChild(scriptTag);
} else {
buildCharts();
}
});
</script>
</head><body><div class="header"><h2>simstr benchmarks results</h2>
<div style="font-size:16pt;margin:20px;text-align:center"><a href="https://github.com/orefkov/simstr">simstr</a> is a powerful and convenient library for productive work with strings in C++.</div>
<span>All times in ns.</span>
<span><a href="https://github.com/orefkov/simstr/blob/main/bench/bench_str.cpp">Source for benchmarks</a></span>
<div>Group tests by platforms in charts: <input type="checkbox" id="gbp" checked onchange="switchGrouping()"/></div><div class="test_platforms"><h3>Test configurations:</h3><ul>
<li><span class="platform">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</span><span class="tooltip">32 X 2494.22 MHz CPU s<span class="tooltiptext">CPU Caches:
L1 Data 32 KiB (x16)
L1 Instruction 32 KiB (x16)
L2 Unified 256 KiB (x16)
L3 Unified 40960 KiB (x1)
Load Average: 0.20, 0.67, 0.53
***WARNING*** ASLR is enabled, the results may have unreproducible noise in them.</span></span>&nbsp;Include in charts: <input type="checkbox" id="pl0" checked onchange="buildCharts()"/></li>
<li><span class="platform">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</span><span class="tooltip">32 X 2494.22 MHz CPU s<span class="tooltiptext">CPU Caches:
L1 Data 32 KiB (x16)
L1 Instruction 32 KiB (x16)
L2 Unified 256 KiB (x16)
L3 Unified 40960 KiB (x1)
Load Average: 0.28, 0.77, 0.74
***WARNING*** ASLR is enabled, the results may have unreproducible noise in them.</span></span>&nbsp;Include in charts: <input type="checkbox" id="pl1" checked onchange="buildCharts()"/></li>
<li><span class="platform">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</span><span class="tooltip">32 X 2494.22 MHz CPU s<span class="tooltiptext">CPU Caches:
L1 Data 32 KiB (x16)
L1 Instruction 32 KiB (x16)
L2 Unified 256 KiB (x16)
L3 Unified 40960 KiB (x1)
Load Average: 0.06, 0.09, 0.08
***WARNING*** ASLR is enabled, the results may have unreproducible noise in them.</span></span>&nbsp;Include in charts: <input type="checkbox" id="pl2" checked onchange="buildCharts()"/></li>
<li><span class="platform">Xeon E5-2682 v4, Windows 10, Clang-22</span><span class="tooltip">32 X 2494 MHz CPU s<span class="tooltiptext">CPU Caches:
L1 Data 32 KiB (x16)
L1 Instruction 32 KiB (x16)
L2 Unified 256 KiB (x16)
L3 Unified 40960 KiB (x1)</span></span>&nbsp;Include in charts: <input type="checkbox" id="pl3" checked onchange="buildCharts()"/></li>
<li><span class="platform">Xeon E5-2682 v4, Windows 10, MSVC-19</span><span class="tooltip">32 X 2494 MHz CPU s<span class="tooltiptext">CPU Caches:
L1 Data 32 KiB (x16)
L1 Instruction 32 KiB (x16)
L2 Unified 256 KiB (x16)
L3 Unified 40960 KiB (x1)</span></span>&nbsp;Include in charts: <input type="checkbox" id="pl4" checked onchange="buildCharts()"/></li>
<li><span class="platform">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</span><span class="tooltip">32 X 2513.96 MHz CPU s<span class="tooltiptext">Chrome/143.0.0.0 webasm</span></span>&nbsp;Include in charts: <input type="checkbox" id="pl5" checked onchange="buildCharts()"/></li>
</ul></div></div>
<script>const platform_names=['Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22','Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++','Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15','Xeon E5-2682 v4, Windows 10, Clang-22','Xeon E5-2682 v4, Windows 10, MSVC-19','Xeon E5-2682 v4, WASM Chrome 143, Clang-22'];</script>
<div class="benchset" id="bs1"><h4><a id="bs15359472366966513900" href="#bs15359472366966513900">#</a>&nbsp;Concatenate email</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L94">Concat email std::format</a><span class="tooltiptext code">std::string email_concat_format(std::string_view name, std::string_view domain, std::string_view tld) {
return std::format(&quot;{}@{}.{}&quot;, name, domain, tld);
}</span></span></td><td></td><td class="benchmarkresult">167</td><td class="benchmarkresult">170</td><td class="benchmarkresult">160</td><td class="benchmarkresult">201</td><td class="benchmarkresult">256</td><td class="benchmarkresult">483</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L109">Concat email std::stringstream</a><span class="tooltiptext code">std::string email_concat_stream(std::string_view name, std::string_view domain, std::string_view tld) {
std::stringstream s;
s &lt;&lt; name &lt;&lt; &quot;@&quot; &lt;&lt; domain &lt;&lt; &quot;.&quot; &lt;&lt; tld;
return s.str();
}</span></span></td><td></td><td class="benchmarkresult">379</td><td class="benchmarkresult">279</td><td class="benchmarkresult">321</td><td class="benchmarkresult">830</td><td class="benchmarkresult">940</td><td class="benchmarkresult">1090</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L60">Concat email stringzilla append</a><span class="tooltiptext code">sz::string email_concat_stringzilla_app(sz::string name, sz::string_view domain, sz::string_view tld) {
return name.append(&quot;@&quot;).append(domain).append(&quot;.&quot;).append(tld);
}</span></span></td><td></td><td class="benchmarkresult">143</td><td class="benchmarkresult">141</td><td class="benchmarkresult">108</td><td class="benchmarkresult">273</td><td class="benchmarkresult">287</td><td class="benchmarkresult">230</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L77">Concat email stringzilla concat</a><span class="tooltiptext code">sz::string email_concat_stringzilla_exp(sz::string name, sz::string_view domain, sz::string_view tld) {
return sz::string{name | sz::string_view{&quot;@&quot;} | domain | sz::string_view{&quot;.&quot;} | tld};
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">В stringzilla тоже есть конкатенация строковыми выражениями, но не
так удобна и развита, как в simstr.
Stringzilla also has concatenation by expression templates,
but it's not as convenient or advanced as simstr.</span></span></td><td class="benchmarkresult">54.6</td><td class="benchmarkresult">55.0</td><td class="benchmarkresult">42.8</td><td class="benchmarkresult">126</td><td class="benchmarkresult">134</td><td class="benchmarkresult">92.5</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L126">Concat email std::string append</a><span class="tooltiptext code">std::string email_concat_std(std::string name, std::string_view domain, std::string_view tld) {
return name.append(&quot;@&quot;).append(domain).append(&quot;.&quot;).append(tld);
}</span></span></td><td></td><td class="benchmarkresult">73.9</td><td class="benchmarkresult">91.0</td><td class="benchmarkresult">79.2</td><td class="benchmarkresult">187</td><td class="benchmarkresult">200</td><td class="benchmarkresult">289</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L142">Concat email std::string by strexpr</a><span class="tooltiptext code">std::string email_concat_std_expr(std::string_view name, std::string_view domain, std::string_view tld) {
return +name + &quot;@&quot; + domain + &quot;.&quot; + tld;
}</span></span></td><td></td><td class="benchmarkresult">46.8</td><td class="benchmarkresult">46.8</td><td class="benchmarkresult">34.4</td><td class="benchmarkresult">104</td><td class="benchmarkresult">113</td><td class="benchmarkresult">88.2</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L157">Concat email stringa</a><span class="tooltiptext code">stringa email_concat_sim_expr(ssa name, ssa domain, ssa tld) {
return name + &quot;@&quot; + domain + &quot;.&quot; + tld;
}</span></span></td><td></td><td class="benchmarkresult">39.1</td><td class="benchmarkresult">38.7</td><td class="benchmarkresult">40.7</td><td class="benchmarkresult">94.4</td><td class="benchmarkresult">106</td><td class="benchmarkresult">67.4</td></tr>
</tbody></table></div><script>bench_sets['Concatenate email'] = {id:'bs1', tests:[
{name:'Concat email std::format',data:[167,170,160,201,256,483]},
{name:'Concat email std::stringstream',data:[379,279,321,830,940,1090]},
{name:'Concat email stringzilla append',data:[143,141,108,273,287,230]},
{name:'Concat email stringzilla concat',data:[54.6,55.0,42.8,126,134,92.5]},
{name:'Concat email std::string append',data:[73.9,91.0,79.2,187,200,289]},
{name:'Concat email std::string by strexpr',data:[46.8,46.8,34.4,104,113,88.2]},
{name:'Concat email stringa',data:[39.1,38.7,40.7,94.4,106,67.4]}
]}</script>
<div class="benchset" id="bs2"><h4><a id="bs70109915512075798510" href="#bs70109915512075798510">#</a>&nbsp;Concatenate string + Number + &quot;Literal&quot;</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L181">Concat std::string and number by std to std::string</a><span class="tooltiptext code">void ConcatStdToStd(benchmark::State&amp; state) {
std::string s1 = &quot;start &quot;;
for (auto _: state) {
for (int i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
std::string str = s1 + std::to_string(i) + &quot; end&quot;;
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">223</td><td class="benchmarkresult">242</td><td class="benchmarkresult">214</td><td class="benchmarkresult">268</td><td class="benchmarkresult">333</td><td class="benchmarkresult">1042</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L192">Concat std::string and number by StrExpr to std::string</a><span class="tooltiptext code">void ConcatSimToStd(benchmark::State&amp; state) {
std::string s1 = &quot;start &quot;;
for (auto _: state) {
for (int i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
std::string str = +s1 + i + &quot; end&quot;;
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">105</td><td class="benchmarkresult">102</td><td class="benchmarkresult">102</td><td class="benchmarkresult">160</td><td class="benchmarkresult">219</td><td class="benchmarkresult">486</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L203">Concat stringa and number by StrExpr to simstr::stringa</a><span class="tooltiptext code">void ConcatSimToSim(benchmark::State&amp; state) {
stra s1 = &quot;start &quot;;
for (auto _: state) {
for (int i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
stringa str = s1 + i + &quot; end&quot;;
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">stringa в отличии от std::string,
вмещает в SSO 23 символа вместо 15, поэтому
в конце теста std::string приходится аллоцировать память,
а в stringa весь тест входит в SSO.
Unlike std::string, stringa
holds 23 characters in SSO instead of 15, so
at the end of the std::string test, memory has to be allocated,
while in stringa , the entire test is included in SSO.</span></span></td><td class="benchmarkresult">64.9</td><td class="benchmarkresult">64.3</td><td class="benchmarkresult">72.3</td><td class="benchmarkresult">68.7</td><td class="benchmarkresult">109</td><td class="benchmarkresult">217</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L214">Concat stringa and number by e_concat to simstr::stringa</a><span class="tooltiptext code">void ConcatSimToSimConcat(benchmark::State&amp; state) {
stra s1 = &quot;start &quot;;
for (auto _: state) {
for (int i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
stringa str = e_concat(&quot;&quot;, s1, i, &quot; end&quot;);
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">72.3</td><td class="benchmarkresult">72.1</td><td class="benchmarkresult">77.7</td><td class="benchmarkresult">74.2</td><td class="benchmarkresult">121</td><td class="benchmarkresult">218</td></tr>
</tbody></table></div><script>bench_sets['Concatenate string + Number + "Literal"'] = {id:'bs2', tests:[
{name:'Concat std::string and number by std to std::string',data:[223,242,214,268,333,1042]},
{name:'Concat std::string and number by StrExpr to std::string',data:[105,102,102,160,219,486]},
{name:'Concat stringa and number by StrExpr to simstr::stringa',data:[64.9,64.3,72.3,68.7,109,217]},
{name:'Concat stringa and number by e_concat to simstr::stringa',data:[72.3,72.1,77.7,74.2,121,218]}
]}</script>
<div class="benchset" id="bs3"><h4><a id="bs146911715078927772520" href="#bs146911715078927772520">#</a>&nbsp;Concatenate string + Hex Number + &quot;Literal&quot;</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L231">Concat std::string and format hex number and literal to std::string</a><span class="tooltiptext code">void ConcatStdToFmtHex(benchmark::State&amp; 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 = &quot;art &quot;;
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
// It is not worked for char8_t, char16_t, char32_t :(
std::string str = s1 + std::format(&quot;{:#x}&quot;, i) + &quot; end&quot;;
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">696</td><td class="benchmarkresult">724</td><td class="benchmarkresult">728</td><td class="benchmarkresult">725</td><td class="benchmarkresult">1030</td><td class="benchmarkresult">2057</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L244">std::format std::string and hex number by literal to std::string</a><span class="tooltiptext code">void ConcatAllFmtToHex(benchmark::State&amp; 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 = &quot;art &quot;;
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
// It is not worked for char8_t, char16_t, char32_t :(
std::string str = std::format(&quot;{}{:#x} end&quot;, s1, i);
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">828</td><td class="benchmarkresult">783</td><td class="benchmarkresult">893</td><td class="benchmarkresult">1525</td><td class="benchmarkresult">1872</td><td class="benchmarkresult">2629</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L256">Concat std::string and std::to_chars and string to std::string</a><span class="tooltiptext code">void ConcatStdToCharsHex(benchmark::State&amp; 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 = &quot;art &quot;;
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;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 + &quot;0x&quot; + std::string(buf, len) + &quot; end&quot;;
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">210</td><td class="benchmarkresult">221</td><td class="benchmarkresult">199</td><td class="benchmarkresult">188</td><td class="benchmarkresult">252</td><td class="benchmarkresult">676</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L271">Concat std::string and hex number and literal by StrExpr to std::string</a><span class="tooltiptext code">void ConcatSimToStdHex(benchmark::State&amp; 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 = &quot;art &quot;;
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
// Can work for all types of symbols
std::string str = +s1 + i / 1_f16 + &quot; end&quot;;
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">134</td><td class="benchmarkresult">150</td><td class="benchmarkresult">125</td><td class="benchmarkresult">84.6</td><td class="benchmarkresult">115</td><td class="benchmarkresult">526</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L284">Concat stringa and hex number and literal by StrExpr to simstr::stringa</a><span class="tooltiptext code">void ConcatSimToSimHex(benchmark::State&amp; state) {
// stringa SSO buffer is 23, but we use a short string to compare under the same conditions
stra s1 = &quot;art &quot;;
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
// Can work for all types of symbols
stringa str = s1 + i / 1_f16 + &quot; end&quot;;
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">117</td><td class="benchmarkresult">120</td><td class="benchmarkresult">122</td><td class="benchmarkresult">71.4</td><td class="benchmarkresult">101</td><td class="benchmarkresult">189</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L297">Concat stringa and hex number and literal by e_concat to simstr::stringa</a><span class="tooltiptext code">void ConcatSimToSimHexC(benchmark::State&amp; state) {
// stringa SSO buffer is 23, but we use a short string to compare under the same conditions
stra s1 = &quot;art &quot;;
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
// Can work for all types of symbols
stringa str = e_concat(&quot;&quot;, s1, i / 1_f16, &quot; end&quot;);
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">128</td><td class="benchmarkresult">124</td><td class="benchmarkresult">125</td><td class="benchmarkresult">76.9</td><td class="benchmarkresult">108</td><td class="benchmarkresult">198</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L310">Subst stringa and hex number by e_subst literal to simstr::stringa</a><span class="tooltiptext code">void ConcatSimToSimHexS(benchmark::State&amp; state) {
// stringa SSO buffer is 23, but we use a short string to compare under the same conditions
stra s1 = &quot;art &quot;;
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
stringa str = e_subst(&quot;{}{} end&quot;, s1, i / 1_f16);
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">193</td><td class="benchmarkresult">187</td><td class="benchmarkresult">172</td><td class="benchmarkresult">149</td><td class="benchmarkresult">173</td><td class="benchmarkresult">355</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L322">Subst stringa and hex number by e_vsubst stra to simstr::stringa</a><span class="tooltiptext code">void ConcatSimToSimHexVS(benchmark::State&amp; state) {
// stringa SSO buffer is 23, but we use a short string to compare under the same conditions
stra s1 = &quot;art &quot;;
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
stringa str = e_vsubst(&quot;{}{} end&quot;_ss, s1, i / 1_f16);
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">333</td><td class="benchmarkresult">332</td><td class="benchmarkresult">280</td><td class="benchmarkresult">287</td><td class="benchmarkresult">361</td><td class="benchmarkresult">843</td></tr>
</tbody></table></div><script>bench_sets['Concatenate string + Hex Number + "Literal"'] = {id:'bs3', tests:[
{name:'Concat std::string and format hex number and literal to std::string',data:[696,724,728,725,1030,2057]},
{name:'std::format std::string and hex number by literal to std::string',data:[828,783,893,1525,1872,2629]},
{name:'Concat std::string and std::to_chars and string to std::string',data:[210,221,199,188,252,676]},
{name:'Concat std::string and hex number and literal by StrExpr to std::string',data:[134,150,125,84.6,115,526]},
{name:'Concat stringa and hex number and literal by StrExpr to simstr::stringa',data:[117,120,122,71.4,101,189]},
{name:'Concat stringa and hex number and literal by e_concat to simstr::stringa',data:[128,124,125,76.9,108,198]},
{name:'Subst stringa and hex number by e_subst literal to simstr::stringa',data:[193,187,172,149,173,355]},
{name:'Subst stringa and hex number by e_vsubst stra to simstr::stringa',data:[333,332,280,287,361,843]}
]}</script>
<div class="benchset" id="bs4"><h4><a id="bs32341904136562619220" href="#bs32341904136562619220">#</a>&nbsp;format/vformat and subst/vsubst octal number to 32 symbols result</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L344">&quot;abcdefghihklmopqr &quot;_ss + i / 0x8a010_fmt + &quot; end&quot;</a><span class="tooltiptext code">void ConcatSimToSimOct(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
stringa str = &quot;abcdefghihklmopqr &quot;_ss + i / 0x8a010_fmt + &quot; end&quot;;
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">271</td><td class="benchmarkresult">278</td><td class="benchmarkresult">261</td><td class="benchmarkresult">639</td><td class="benchmarkresult">702</td><td class="benchmarkresult">414</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L353">e_subst(&quot;abcdefghihklmopqr {} end&quot;, i / 0x8a010_fmt)</a><span class="tooltiptext code">void SubstSimToSimOct(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
stringa str = e_subst(&quot;abcdefghihklmopqr {} end&quot;, i / 0x8a010_fmt);
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">357</td><td class="benchmarkresult">358</td><td class="benchmarkresult">315</td><td class="benchmarkresult">750</td><td class="benchmarkresult">810</td><td class="benchmarkresult">621</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L362">e_vsubst(pattern, i / 0x8a010_fmt)</a><span class="tooltiptext code">void VSubstSimToSimOct(benchmark::State&amp; state) {
ssa pattern = &quot;abcdefghihklmopqr {} end&quot;;
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
stringa str = e_vsubst(pattern, i / 0x8a010_fmt);
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">621</td><td class="benchmarkresult">608</td><td class="benchmarkresult">593</td><td class="benchmarkresult">1070</td><td class="benchmarkresult">1144</td><td class="benchmarkresult">1426</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L402">fmt::format(FMT_COMPILE(&quot;abcdefghihklmopqr {:#010o} end&quot;), i)</a><span class="tooltiptext code">void FmtFormatComp(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
std::string str = fmt::format(FMT_COMPILE(&quot;abcdefghihklmopqr {:#010o} end&quot;), i);
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">723</td><td class="benchmarkresult">697</td><td class="benchmarkresult">629</td><td class="benchmarkresult">1433</td><td class="benchmarkresult">1583</td><td class="benchmarkresult">2149</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L411">fmt::format(&quot;abcdefghihklmopqr {:#010o} end&quot;, i)</a><span class="tooltiptext code">void FmtFormat(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
std::string str = fmt::format(&quot;abcdefghihklmopqr {:#010o} end&quot;, i);
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">842</td><td class="benchmarkresult">814</td><td class="benchmarkresult">788</td><td class="benchmarkresult">1327</td><td class="benchmarkresult">1596</td><td class="benchmarkresult">2879</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L372">std::format(&quot;abcdefghihklmopqr {:#010o} end&quot;, i)</a><span class="tooltiptext code">void FormatStdToStdOct(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
std::string str = std::format(&quot;abcdefghihklmopqr {:#010o} end&quot;, i);
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">1017</td><td class="benchmarkresult">1268</td><td class="benchmarkresult">1171</td><td class="benchmarkresult">1568</td><td class="benchmarkresult">1946</td><td class="benchmarkresult">2940</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L381">std::vformat(pattern, std::make_format_args(i))</a><span class="tooltiptext code">void VFormatStdToStdOct(benchmark::State&amp; state) {
std::string_view pattern = &quot;abcdefghihklmopqr {:#010o} end&quot;;
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
std::string str = std::vformat(pattern, std::make_format_args(i));
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">999</td><td class="benchmarkresult">1228</td><td class="benchmarkresult">1176</td><td class="benchmarkresult">1555</td><td class="benchmarkresult">1990</td><td class="benchmarkresult">2985</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L421">std::format with std::formatted_size</a><span class="tooltiptext code">void StdFormatSize(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
size_t len = std::formatted_size(&quot;abcdefghihklmopqr {:#010o} end&quot;, i);
std::string str;
str.resize_and_overwrite(len, [&amp;](char* p, size_t) {
std::format_to_n(str.data(), len, &quot;abcdefghihklmopqr {:#010o} end&quot;, i);
return len;
});
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">1867</td><td class="benchmarkresult">2175</td><td class="benchmarkresult">2267</td><td class="benchmarkresult">2496</td><td class="benchmarkresult">2922</td><td class="benchmarkresult">5263</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L391">strm &lt;&lt; &quot;abcdefghihklmopqr 0&quot; &lt;&lt; std::oct &lt;&lt; std::setw(9) &lt;&lt; std::setfill(&#39;0&#39;) &lt;&lt; i &lt;&lt; &quot; end&quot;</a><span class="tooltiptext code">void StreamStdToStdOct(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned i = 1; i &lt;= 100&#39;000; i *= 10) {
std::stringstream strm;
strm &lt;&lt; &quot;abcdefghihklmopqr 0&quot; &lt;&lt; std::oct &lt;&lt; std::setw(9) &lt;&lt; std::setfill(&#39;0&#39;) &lt;&lt; i &lt;&lt; &quot; end&quot;;
std::string str = strm.str();
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">2074</td><td class="benchmarkresult">2608</td><td class="benchmarkresult">2021</td><td class="benchmarkresult">6707</td><td class="benchmarkresult">7026</td><td class="benchmarkresult">8433</td></tr>
</tbody></table></div><script>bench_sets['format/vformat and subst/vsubst octal number to 32 symbols result'] = {id:'bs4', tests:[
{name:'"abcdefghihklmopqr "_ss + i / 0x8a010_fmt + " end"',data:[271,278,261,639,702,414]},
{name:'e_subst("abcdefghihklmopqr {} end", i / 0x8a010_fmt)',data:[357,358,315,750,810,621]},
{name:'e_vsubst(pattern, i / 0x8a010_fmt)',data:[621,608,593,1070,1144,1426]},
{name:'fmt::format(FMT_COMPILE("abcdefghihklmopqr {:#010o} end"), i)',data:[723,697,629,1433,1583,2149]},
{name:'fmt::format("abcdefghihklmopqr {:#010o} end", i)',data:[842,814,788,1327,1596,2879]},
{name:'std::format("abcdefghihklmopqr {:#010o} end", i)',data:[1017,1268,1171,1568,1946,2940]},
{name:'std::vformat(pattern, std::make_format_args(i))',data:[999,1228,1176,1555,1990,2985]},
{name:'std::format with std::formatted_size',data:[1867,2175,2267,2496,2922,5263]},
{name:'strm << "abcdefghihklmopqr 0" << std::oct << std::setw(9) << std::setfill(\'0\') << i << " end"',data:[2074,2608,2021,6707,7026,8433]}
]}</script>
<div class="benchset" id="bs5"><h4><a id="bs59672599204338055190" href="#bs59672599204338055190">#</a>&nbsp;Concatenate string + &quot;Literal&quot;</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L446">Concat std::string by std to std::string</a><span class="tooltiptext code">void ConcatStdToStdS(benchmark::State&amp; state) {
std::string s1 = &quot;start &quot;;
for (auto _: state) {
for (int i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
std::string str = s1 + &quot; end&quot;;
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">51.7</td><td class="benchmarkresult">34.1</td><td class="benchmarkresult">47.9</td><td class="benchmarkresult">42.2</td><td class="benchmarkresult">55.5</td><td class="benchmarkresult">109</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L457">Concat std::string by StrExpr to std::string</a><span class="tooltiptext code">void ConcatSimToStdS(benchmark::State&amp; state) {
std::string s1 = &quot;start &quot;;
for (auto _: state) {
for (int i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
std::string str = +s1 + &quot; end&quot;;
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">36.9</td><td class="benchmarkresult">37.3</td><td class="benchmarkresult">35.3</td><td class="benchmarkresult">39.3</td><td class="benchmarkresult">77.4</td><td class="benchmarkresult">120</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L468">Concat stringa by StrExpr to stringa</a><span class="tooltiptext code">void ConcatSimToSimS(benchmark::State&amp; state) {
stra s1 = &quot;start &quot;;
for (auto _: state) {
for (int i = 1; i &lt;= 100&#39;000; i *= 10) {
benchmark::DoNotOptimize(s1);
stringa str = s1 + &quot; end&quot;;
benchmark::DoNotOptimize(str);
}
}
}</span></span></td><td></td><td class="benchmarkresult">31.6</td><td class="benchmarkresult">28.3</td><td class="benchmarkresult">27.4</td><td class="benchmarkresult">30.6</td><td class="benchmarkresult">52.2</td><td class="benchmarkresult">95.4</td></tr>
</tbody></table></div><script>bench_sets['Concatenate string + "Literal"'] = {id:'bs5', tests:[
{name:'Concat std::string by std to std::string',data:[51.7,34.1,47.9,42.2,55.5,109]},
{name:'Concat std::string by StrExpr to std::string',data:[36.9,37.3,35.3,39.3,77.4,120]},
{name:'Concat stringa by StrExpr to stringa',data:[31.6,28.3,27.4,30.6,52.2,95.4]}
]}</script>
<div class="benchset" id="bs6"><h4><a id="bs68116594352702954700" href="#bs68116594352702954700">#</a>&nbsp;Find three concatenated string in string_view</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L484">Find concat three std::string</a><span class="tooltiptext code">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(&quot;\n- &quot;s + std::string{name} + &quot; -\n&quot;);
}</span></span></td><td></td><td class="benchmarkresult">112</td><td class="benchmarkresult">92.4</td><td class="benchmarkresult">119</td><td class="benchmarkresult">206</td><td class="benchmarkresult">230</td><td class="benchmarkresult">214</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L489">Find concat three strexpr</a><span class="tooltiptext code">size_t find_pos_exp(ssa src, ssa name) {
return src.find(std::string{&quot;\n- &quot; + name + &quot; -\n&quot;});
}</span></span></td><td></td><td class="benchmarkresult">52.4</td><td class="benchmarkresult">46.5</td><td class="benchmarkresult">38.2</td><td class="benchmarkresult">113</td><td class="benchmarkresult">138</td><td class="benchmarkresult">100.0</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L493">Find concat three simstr</a><span class="tooltiptext code">size_t find_pos_sim(ssa src, ssa name) {
return src.find(lstringa&lt;200>{&quot;\n- &quot; + name + &quot; -\n&quot;});
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Если результат конкатенации меньше 207 символов,
он собирается в буфере на стеке, без аллокации и деалокации.
If the concatenation result is less than 207 characters,
it is collected in a stack-based buffer, without allocation or deallocation.</span></span></td><td class="benchmarkresult">18.9</td><td class="benchmarkresult">17.0</td><td class="benchmarkresult">15.6</td><td class="benchmarkresult">21.2</td><td class="benchmarkresult">28.3</td><td class="benchmarkresult">58.2</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L497">Find concat three stringzilla string</a><span class="tooltiptext code">size_t find_pos_sz(sz::string_view src, sz::string_view name) {
return src.find(sz::string{&quot;\n- &quot;}.append(name).append(&quot; -\n&quot;));
}</span></span></td><td></td><td class="benchmarkresult">153</td><td class="benchmarkresult">176</td><td class="benchmarkresult">125</td><td class="benchmarkresult">215</td><td class="benchmarkresult">232</td><td class="benchmarkresult">268</td></tr>
</tbody></table></div><script>bench_sets['Find three concatenated string in string_view'] = {id:'bs6', tests:[
{name:'Find concat three std::string',data:[112,92.4,119,206,230,214]},
{name:'Find concat three strexpr',data:[52.4,46.5,38.2,113,138,100.0]},
{name:'Find concat three simstr',data:[18.9,17.0,15.6,21.2,28.3,58.2]},
{name:'Find concat three stringzilla string',data:[153,176,125,215,232,268]}
]}</script>
<div class="benchset" id="bs7"><h4><a id="bs145290966789248325200" href="#bs145290966789248325200">#</a>&nbsp;Build Type Name</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L573">BuildTypeNameStr 0/0</a><span class="tooltiptext code">std::string buildTypeNameStr(std::string_view type_name, size_t prec, size_t scale) {
std::string res{type_name};
if (prec) {
res += &quot;(&quot; + std::to_string(prec);
if (scale) {
res += &quot;,&quot; + std::to_string(scale);
}
res += &quot;)&quot;;
}
return res;
}</span></span></td><td></td><td class="benchmarkresult">7.58</td><td class="benchmarkresult">6.45</td><td class="benchmarkresult">8.65</td><td class="benchmarkresult">8.34</td><td class="benchmarkresult">17.8</td><td class="benchmarkresult">20.9</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L585">BuildTypeNameExp 0/0</a><span class="tooltiptext code">std::string buildTypeNameExp(ssa type_name, size_t prec, size_t scale) {
if (prec) {
return type_name + &quot;(&quot; + prec + e_if(scale, &quot;,&quot;_ss + scale) + &quot;)&quot;;
}
return type_name;
}</span></span></td><td></td><td class="benchmarkresult">6.94</td><td class="benchmarkresult">6.41</td><td class="benchmarkresult">6.99</td><td class="benchmarkresult">7.67</td><td class="benchmarkresult">14.4</td><td class="benchmarkresult">23.1</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L592">BuildTypeNameSim 0/0</a><span class="tooltiptext code">stringa buildTypeNameSim(ssa type_name, size_t prec, size_t scale) {
if (prec) {
return type_name + &quot;(&quot; + prec + e_if(scale, &quot;,&quot;_ss + scale) + &quot;)&quot;;
}
return type_name;
}</span></span></td><td></td><td class="benchmarkresult">5.03</td><td class="benchmarkresult">4.99</td><td class="benchmarkresult">4.97</td><td class="benchmarkresult">7.90</td><td class="benchmarkresult">15.4</td><td class="benchmarkresult">20.4</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L573">BuildTypeNameStr 10/10</a><span class="tooltiptext code">std::string buildTypeNameStr(std::string_view type_name, size_t prec, size_t scale) {
std::string res{type_name};
if (prec) {
res += &quot;(&quot; + std::to_string(prec);
if (scale) {
res += &quot;,&quot; + std::to_string(scale);
}
res += &quot;)&quot;;
}
return res;
}</span></span></td><td></td><td class="benchmarkresult">59.1</td><td class="benchmarkresult">90.0</td><td class="benchmarkresult">76.6</td><td class="benchmarkresult">79.5</td><td class="benchmarkresult">80.1</td><td class="benchmarkresult">365</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L585">BuildTypeNameExp 10/10</a><span class="tooltiptext code">std::string buildTypeNameExp(ssa type_name, size_t prec, size_t scale) {
if (prec) {
return type_name + &quot;(&quot; + prec + e_if(scale, &quot;,&quot;_ss + scale) + &quot;)&quot;;
}
return type_name;
}</span></span></td><td></td><td class="benchmarkresult">31.0</td><td class="benchmarkresult">39.0</td><td class="benchmarkresult">27.9</td><td class="benchmarkresult">33.1</td><td class="benchmarkresult">39.4</td><td class="benchmarkresult">116</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L592">BuildTypeNameSim 10/10</a><span class="tooltiptext code">stringa buildTypeNameSim(ssa type_name, size_t prec, size_t scale) {
if (prec) {
return type_name + &quot;(&quot; + prec + e_if(scale, &quot;,&quot;_ss + scale) + &quot;)&quot;;
}
return type_name;
}</span></span></td><td></td><td class="benchmarkresult">23.4</td><td class="benchmarkresult">23.6</td><td class="benchmarkresult">22.6</td><td class="benchmarkresult">25.2</td><td class="benchmarkresult">38.8</td><td class="benchmarkresult">69.0</td></tr>
</tbody></table></div><script>bench_sets['Build Type Name'] = {id:'bs7', tests:[
{name:'BuildTypeNameStr 0/0',data:[7.58,6.45,8.65,8.34,17.8,20.9]},
{name:'BuildTypeNameExp 0/0',data:[6.94,6.41,6.99,7.67,14.4,23.1]},
{name:'BuildTypeNameSim 0/0',data:[5.03,4.99,4.97,7.90,15.4,20.4]},
{name:'BuildTypeNameStr 10/10',data:[59.1,90.0,76.6,79.5,80.1,365]},
{name:'BuildTypeNameExp 10/10',data:[31.0,39.0,27.9,33.1,39.4,116]},
{name:'BuildTypeNameSim 10/10',data:[23.4,23.6,22.6,25.2,38.8,69.0]}
]}</script>
<div class="benchset" id="bs8"><h4><a id="bs54035654251116789780" href="#bs54035654251116789780">#</a>&nbsp;Replace string by copy</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L646">Concat with replace str</a><span class="tooltiptext code">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 &quot;&lt;&quot; + str_replace(from, pattern, repl) + &quot;>&quot;;
}</span></span></td><td></td><td class="benchmarkresult">210</td><td class="benchmarkresult">243</td><td class="benchmarkresult">236</td><td class="benchmarkresult">315</td><td class="benchmarkresult">352</td><td class="benchmarkresult">500</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L664">Concat with replace exp</a><span class="tooltiptext code">std::string make_str_exp(std::string_view from, std::string_view pattern, std::string_view repl) {
return &quot;&lt;&quot; + e_repl(from, pattern, repl) + &quot;>&quot;;
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">В simstr строковое выражение для замены подстрок
есть "из коробки".
simstr has a string expression for replacing substrings out of the box.</span></span></td><td class="benchmarkresult">154</td><td class="benchmarkresult">151</td><td class="benchmarkresult">135</td><td class="benchmarkresult">220</td><td class="benchmarkresult">222</td><td class="benchmarkresult">235</td></tr>
</tbody></table></div><script>bench_sets['Replace string by copy'] = {id:'bs8', tests:[
{name:'Concat with replace str',data:[210,243,236,315,352,500]},
{name:'Concat with replace exp',data:[154,151,135,220,222,235]}
]}</script>
<div class="benchset" id="bs9"><h4><a id="bs77666948964429305550" href="#bs77666948964429305550">#</a>&nbsp;Create Empty Str</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L698">std::string e;</a><span class="tooltiptext code">template&lt;typename T>
void CreateEmpty(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string;
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Пустые строки, ничего необычного.
Empty lines, nothing unusual.</span></span></td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">0.758</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">2.58</td><td class="benchmarkresult">2.15</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L698">std::string_view e;</a><span class="tooltiptext code">template&lt;typename T>
void CreateEmpty(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string;
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td></td><td class="benchmarkresult">0.377</td><td class="benchmarkresult">0.380</td><td class="benchmarkresult">0.754</td><td class="benchmarkresult">0.369</td><td class="benchmarkresult">1.84</td><td class="benchmarkresult">0.740</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L698">ssa e;</a><span class="tooltiptext code">template&lt;typename T>
void CreateEmpty(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string;
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td></td><td class="benchmarkresult">0.372</td><td class="benchmarkresult">0.375</td><td class="benchmarkresult">0.187</td><td class="benchmarkresult">0.362</td><td class="benchmarkresult">1.86</td><td class="benchmarkresult">0.378</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L698">stringa e;</a><span class="tooltiptext code">template&lt;typename T>
void CreateEmpty(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string;
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td></td><td class="benchmarkresult">0.763</td><td class="benchmarkresult">0.754</td><td class="benchmarkresult">0.753</td><td class="benchmarkresult">0.745</td><td class="benchmarkresult">2.22</td><td class="benchmarkresult">2.15</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L698">lstringa&lt;20> e;</a><span class="tooltiptext code">template&lt;typename T>
void CreateEmpty(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string;
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td></td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.10</td><td class="benchmarkresult">2.55</td><td class="benchmarkresult">2.20</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L698">lstringa&lt;40> e;</a><span class="tooltiptext code">template&lt;typename T>
void CreateEmpty(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string;
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td></td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.11</td><td class="benchmarkresult">2.57</td><td class="benchmarkresult">2.20</td></tr>
</tbody></table></div><script>bench_sets['Create Empty Str'] = {id:'bs9', tests:[
{name:'std::string e;',data:[1.13,0.758,1.13,1.12,2.58,2.15]},
{name:'std::string_view e;',data:[0.377,0.380,0.754,0.369,1.84,0.740]},
{name:'ssa e;',data:[0.372,0.375,0.187,0.362,1.86,0.378]},
{name:'stringa e;',data:[0.763,0.754,0.753,0.745,2.22,2.15]},
{name:'lstringa<20> e;',data:[1.14,1.13,1.14,1.10,2.55,2.20]},
{name:'lstringa<40> e;',data:[1.14,1.14,1.15,1.11,2.57,2.20]}
]}</script>
<div class="benchset" id="bs10"><h4><a id="bs181001525395597238060" href="#bs181001525395597238060">#</a>&nbsp;Create Str from short literal (9 symbols)</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L713">std::string e = &quot;Test text&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void CreateShortLiteral(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string = TEST_TEXT;
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Короткий литерал помещается во внутренний буфер std::string,
время тратится только на копирование 10 байтов.
The short literal is placed in the internal std::string buffer;
time is spent only copying 10 bytes.</span></span></td><td class="benchmarkresult">1.87</td><td class="benchmarkresult">1.51</td><td class="benchmarkresult">1.89</td><td class="benchmarkresult">1.84</td><td class="benchmarkresult">2.57</td><td class="benchmarkresult">2.47</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L713">std::string_view e = &quot;Test text&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void CreateShortLiteral(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string = TEST_TEXT;
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">И string_view, и ssa - по сути одно и то же:
указатель на текст и его длина.
Both string_view and ssa are essentially the same thing:
a pointer to text and its length.</span></span></td><td class="benchmarkresult">0.761</td><td class="benchmarkresult">0.767</td><td class="benchmarkresult">0.754</td><td class="benchmarkresult">0.741</td><td class="benchmarkresult">1.84</td><td class="benchmarkresult">1.12</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L713">ssa e = &quot;Test text&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void CreateShortLiteral(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string = TEST_TEXT;
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td></td><td class="benchmarkresult">0.382</td><td class="benchmarkresult">0.381</td><td class="benchmarkresult">0.757</td><td class="benchmarkresult">0.369</td><td class="benchmarkresult">1.84</td><td class="benchmarkresult">0.744</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L713">stringa e = &quot;Test text&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void CreateShortLiteral(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string = TEST_TEXT;
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">stringa при инициализации константным литералом так же
сохраняет только указатель на текст и его длину.
When initialized with a constant literal, stringa also stores
only a pointer to the text and its length.</span></span></td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.11</td><td class="benchmarkresult">2.57</td><td class="benchmarkresult">2.19</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L713">lstringa&lt;20> e = &quot;Test text&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void CreateShortLiteral(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string = TEST_TEXT;
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Внутреннего буфера хватает для размещения символов,
время уходит только на копирование байтов.
The internal buffer is sufficient to accommodate characters;
time is spent only on copying bytes.</span></span></td><td class="benchmarkresult">1.90</td><td class="benchmarkresult">1.89</td><td class="benchmarkresult">1.92</td><td class="benchmarkresult">1.84</td><td class="benchmarkresult">2.60</td><td class="benchmarkresult">2.63</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L713">lstringa&lt;40> e = &quot;Test text&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void CreateShortLiteral(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string = TEST_TEXT;
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td></td><td class="benchmarkresult">1.88</td><td class="benchmarkresult">1.86</td><td class="benchmarkresult">1.90</td><td class="benchmarkresult">1.85</td><td class="benchmarkresult">2.58</td><td class="benchmarkresult">2.61</td></tr>
</tbody></table></div><script>bench_sets['Create Str from short literal (9 symbols)'] = {id:'bs10', tests:[
{name:'std::string e = "Test text";',data:[1.87,1.51,1.89,1.84,2.57,2.47]},
{name:'std::string_view e = "Test text";',data:[0.761,0.767,0.754,0.741,1.84,1.12]},
{name:'ssa e = "Test text";',data:[0.382,0.381,0.757,0.369,1.84,0.744]},
{name:'stringa e = "Test text";',data:[1.15,1.13,1.13,1.11,2.57,2.19]},
{name:'lstringa<20> e = "Test text";',data:[1.90,1.89,1.92,1.84,2.60,2.63]},
{name:'lstringa<40> e = "Test text";',data:[1.88,1.86,1.90,1.85,2.58,2.61]}
]}</script>
<div class="benchset" id="bs11"><h4><a id="bs132333183298742730280" href="#bs132333183298742730280">#</a>&nbsp;Create Str from long literal (30 symbols)</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L728">std::string e = &quot;123456789012345678901234567890&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void CreateLongLiteral(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string{LONG_TEXT};
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Вот тут уже литерал не помещается во внутренний буфер,
возникает аллокация и копирование 30-и байтов.
Но как же отстает аллокация под Windows от Linux'а, 20 vs 70 ns...
Here, the literal doesn't fit into the internal buffer,
and 30 bytes are allocated and copied.
But how much slower is allocation under Windows than under Linux, 20 ns vs. 70 ns...</span></span></td><td class="benchmarkresult">19.5</td><td class="benchmarkresult">19.3</td><td class="benchmarkresult">19.7</td><td class="benchmarkresult">73.9</td><td class="benchmarkresult">79.3</td><td class="benchmarkresult">21.8</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L728">std::string_view e = &quot;123456789012345678901234567890&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void CreateLongLiteral(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string{LONG_TEXT};
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">string_view и ssa по прежнему ничего не делают, кроме
запоминания указателя на текст и его размера.
string_view and ssa still do nothing except
remember the pointer to the text and its size.</span></span></td><td class="benchmarkresult">0.763</td><td class="benchmarkresult">0.745</td><td class="benchmarkresult">0.751</td><td class="benchmarkresult">0.736</td><td class="benchmarkresult">1.86</td><td class="benchmarkresult">1.10</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L728">ssa e = &quot;123456789012345678901234567890&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void CreateLongLiteral(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string{LONG_TEXT};
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td></td><td class="benchmarkresult">0.375</td><td class="benchmarkresult">0.374</td><td class="benchmarkresult">0.761</td><td class="benchmarkresult">0.369</td><td class="benchmarkresult">1.86</td><td class="benchmarkresult">0.741</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L728">stringa e = &quot;123456789012345678901234567890&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void CreateLongLiteral(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string{LONG_TEXT};
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">stringa на константных литералах не отстает!
stringa doesn't lag behind on constant literals!</span></span></td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.11</td><td class="benchmarkresult">2.24</td><td class="benchmarkresult">2.22</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L728">lstringa&lt;20> e = &quot;123456789012345678901234567890&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void CreateLongLiteral(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string{LONG_TEXT};
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">lstringa<20> может вместить в себя до 23 символов,
Очевидно, что для 30-и символов уже нужна аллокация.
Obviously, 30 characters already require allocation.</span></span></td><td class="benchmarkresult">18.0</td><td class="benchmarkresult">18.9</td><td class="benchmarkresult">18.3</td><td class="benchmarkresult">73.1</td><td class="benchmarkresult">72.7</td><td class="benchmarkresult">22.0</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L728">lstringa&lt;40> e = &quot;123456789012345678901234567890&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void CreateLongLiteral(benchmark::State&amp; state) {
for (auto _: state) {
T empty_string{LONG_TEXT};
benchmark::DoNotOptimize(empty_string);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">А в lstringa<40> влезает до 47 символов, так что просто
копируется 30 байтов.
And lstringa<40> can hold up to 47 characters, so 30
bytes are simply copied.</span></span></td><td class="benchmarkresult">2.68</td><td class="benchmarkresult">1.89</td><td class="benchmarkresult">1.91</td><td class="benchmarkresult">2.56</td><td class="benchmarkresult">3.32</td><td class="benchmarkresult">2.98</td></tr>
</tbody></table></div><script>bench_sets['Create Str from long literal (30 symbols)'] = {id:'bs11', tests:[
{name:'std::string e = "123456789012345678901234567890";',data:[19.5,19.3,19.7,73.9,79.3,21.8]},
{name:'std::string_view e = "123456789012345678901234567890";',data:[0.763,0.745,0.751,0.736,1.86,1.10]},
{name:'ssa e = "123456789012345678901234567890";',data:[0.375,0.374,0.761,0.369,1.86,0.741]},
{name:'stringa e = "123456789012345678901234567890";',data:[1.14,1.12,1.13,1.11,2.24,2.22]},
{name:'lstringa<20> e = "123456789012345678901234567890";',data:[18.0,18.9,18.3,73.1,72.7,22.0]},
{name:'lstringa<40> e = "123456789012345678901234567890";',data:[2.68,1.89,1.91,2.56,3.32,2.98]}
]}</script>
<div class="benchset" id="bs12"><h4><a id="bs6234433963744178700" href="#bs6234433963744178700">#</a>&nbsp;Create copy of Str with 9 symbols</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L743">std::string e = &quot;Test text&quot;; auto c{e};</a><span class="tooltiptext code">template&lt;typename T>
void CopyShortString(benchmark::State&amp; state) {
T x{TEST_TEXT};
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Строка в пределах SSO, так что просто копирует байты.
The string is within the SSO, so it just copies the bytes.</span></span></td><td class="benchmarkresult">5.77</td><td class="benchmarkresult">1.18</td><td class="benchmarkresult">5.03</td><td class="benchmarkresult">1.84</td><td class="benchmarkresult">5.40</td><td class="benchmarkresult">3.72</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L743">std::string_view e = &quot;Test text&quot;; auto c{e};</a><span class="tooltiptext code">template&lt;typename T>
void CopyShortString(benchmark::State&amp; state) {
T x{TEST_TEXT};
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">0.388</td><td class="benchmarkresult">0.377</td><td class="benchmarkresult">0.388</td><td class="benchmarkresult">0.373</td><td class="benchmarkresult">2.95</td><td class="benchmarkresult">1.10</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L743">ssa e = &quot;Test text&quot;; auto c{e};</a><span class="tooltiptext code">template&lt;typename T>
void CopyShortString(benchmark::State&amp; state) {
T x{TEST_TEXT};
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">ssa и string_view не владеют строкой, копируется
только информация о строке.
ssa and string_view don't own the string; only the
string information is copied.</span></span></td><td class="benchmarkresult">0.380</td><td class="benchmarkresult">0.378</td><td class="benchmarkresult">0.388</td><td class="benchmarkresult">0.380</td><td class="benchmarkresult">2.95</td><td class="benchmarkresult">1.11</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L743">stringa e = &quot;Test text&quot;; auto c{e};</a><span class="tooltiptext code">template&lt;typename T>
void CopyShortString(benchmark::State&amp; state) {
T x{TEST_TEXT};
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Копирование stringa происходит быстро,
особенно если она инициализирована литералом.
Copying a stringa is fast,
especially if it is initialized with a literal.</span></span></td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.10</td><td class="benchmarkresult">4.12</td><td class="benchmarkresult">2.53</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L743">lstringa&lt;20> e = &quot;Test text&quot;; auto c{e};</a><span class="tooltiptext code">template&lt;typename T>
void CopyShortString(benchmark::State&amp; state) {
T x{TEST_TEXT};
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">В обоих случаях хватает внутреннего буфера.
In both cases, the internal buffer is sufficient.</span></span></td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">4.78</td><td class="benchmarkresult">4.17</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L743">lstringa&lt;40> e = &quot;Test text&quot;; auto c{e};</a><span class="tooltiptext code">template&lt;typename T>
void CopyShortString(benchmark::State&amp; state) {
T x{TEST_TEXT};
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Только копируются байты.
Only bytes are copied.</span></span></td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.85</td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.11</td><td class="benchmarkresult">5.49</td><td class="benchmarkresult">4.49</td></tr>
</tbody></table></div><script>bench_sets['Create copy of Str with 9 symbols'] = {id:'bs12', tests:[
{name:'std::string e = "Test text"; auto c{e};',data:[5.77,1.18,5.03,1.84,5.40,3.72]},
{name:'std::string_view e = "Test text"; auto c{e};',data:[0.388,0.377,0.388,0.373,2.95,1.10]},
{name:'ssa e = "Test text"; auto c{e};',data:[0.380,0.378,0.388,0.380,2.95,1.11]},
{name:'stringa e = "Test text"; auto c{e};',data:[1.12,1.13,1.13,1.10,4.12,2.53]},
{name:'lstringa<20> e = "Test text"; auto c{e};',data:[1.14,1.12,1.15,1.12,4.78,4.17]},
{name:'lstringa<40> e = "Test text"; auto c{e};',data:[1.15,1.85,1.15,1.11,5.49,4.49]}
]}</script>
<div class="benchset" id="bs13"><h4><a id="bs76384575499199461500" href="#bs76384575499199461500">#</a>&nbsp;Create copy of Str with 30 symbols</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L760">std::string e = &quot;123456789012345678901234567890&quot;; auto c{e};</a><span class="tooltiptext code">template&lt;typename T>
void CopyLongString(benchmark::State&amp; state) {
T x = LONG_TEXT;
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Копирования длинной строки вызывает аллокацию,
SSO уже не хватает. И снова как же отстаёт аллокация под Windows...
Copying a long string causes allocations,
SSO is no longer sufficient. And again, how allocation lags under Windows...</span></span></td><td class="benchmarkresult">20.2</td><td class="benchmarkresult">24.9</td><td class="benchmarkresult">23.2</td><td class="benchmarkresult">78.0</td><td class="benchmarkresult">78.8</td><td class="benchmarkresult">46.5</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L760">std::string_view e = &quot;123456789012345678901234567890&quot;; auto c{e};</a><span class="tooltiptext code">template&lt;typename T>
void CopyLongString(benchmark::State&amp; state) {
T x = LONG_TEXT;
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
}
}</span></span></td><td></td><td class="benchmarkresult">0.758</td><td class="benchmarkresult">0.757</td><td class="benchmarkresult">0.759</td><td class="benchmarkresult">0.734</td><td class="benchmarkresult">1.50</td><td class="benchmarkresult">1.11</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L760">ssa e = &quot;123456789012345678901234567890&quot;; auto c{e};</a><span class="tooltiptext code">template&lt;typename T>
void CopyLongString(benchmark::State&amp; state) {
T x = LONG_TEXT;
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
}
}</span></span></td><td></td><td class="benchmarkresult">0.374</td><td class="benchmarkresult">0.381</td><td class="benchmarkresult">0.758</td><td class="benchmarkresult">0.377</td><td class="benchmarkresult">1.47</td><td class="benchmarkresult">0.750</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L760">stringa e = &quot;123456789012345678901234567890&quot;; auto c{e};</a><span class="tooltiptext code">template&lt;typename T>
void CopyLongString(benchmark::State&amp; state) {
T x = LONG_TEXT;
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">А вот у stringa копирование литерала не зависит от его длины,
сравни с предыдущим бенчмарком.
But with stringa, literal copying doesn't depend on its length,
compare with the previous benchmark.</span></span></td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">6.85</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">2.98</td><td class="benchmarkresult">2.21</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L760">lstringa&lt;20> e = &quot;123456789012345678901234567890&quot;; auto c{e};</a><span class="tooltiptext code">template&lt;typename T>
void CopyLongString(benchmark::State&amp; state) {
T x = LONG_TEXT;
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Не влезает, аллокация.
Doesn't fit, allocation.</span></span></td><td class="benchmarkresult">19.1</td><td class="benchmarkresult">18.0</td><td class="benchmarkresult">17.7</td><td class="benchmarkresult">72.6</td><td class="benchmarkresult">82.9</td><td class="benchmarkresult">21.2</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L760">lstringa&lt;40> e = &quot;123456789012345678901234567890&quot;; auto c{e};</a><span class="tooltiptext code">template&lt;typename T>
void CopyLongString(benchmark::State&amp; state) {
T x = LONG_TEXT;
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Уложили во внутренний буфер.
Placed in the internal buffer.</span></span></td><td class="benchmarkresult">4.98</td><td class="benchmarkresult">5.53</td><td class="benchmarkresult">4.18</td><td class="benchmarkresult">5.42</td><td class="benchmarkresult">7.41</td><td class="benchmarkresult">15.8</td></tr>
</tbody></table></div><script>bench_sets['Create copy of Str with 30 symbols'] = {id:'bs13', tests:[
{name:'std::string e = "123456789012345678901234567890"; auto c{e};',data:[20.2,24.9,23.2,78.0,78.8,46.5]},
{name:'std::string_view e = "123456789012345678901234567890"; auto c{e};',data:[0.758,0.757,0.759,0.734,1.50,1.11]},
{name:'ssa e = "123456789012345678901234567890"; auto c{e};',data:[0.374,0.381,0.758,0.377,1.47,0.750]},
{name:'stringa e = "123456789012345678901234567890"; auto c{e};',data:[1.14,1.14,6.85,1.12,2.98,2.21]},
{name:'lstringa<20> e = "123456789012345678901234567890"; auto c{e};',data:[19.1,18.0,17.7,72.6,82.9,21.2]},
{name:'lstringa<40> e = "123456789012345678901234567890"; auto c{e};',data:[4.98,5.53,4.18,5.42,7.41,15.8]}
]}</script>
<div class="benchset" id="bs14"><h4><a id="bs21623892135774528620" href="#bs21623892135774528620">#</a>&nbsp;Find 9 symbols text in end of 99 symbols text</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">sz::string::find;</a><span class="tooltiptext code">template&lt;typename T>
void Find(benchmark::State&amp; 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(&quot;not find?&quot;);
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">stringzilla более заточена на поиск больших строк в больших строках.
stringzilla is more focused on searching large strings within large strings.</span></span></td><td class="benchmarkresult">95.9</td><td class="benchmarkresult">96.5</td><td class="benchmarkresult">87.9</td><td class="benchmarkresult">94.8</td><td class="benchmarkresult">117</td><td class="benchmarkresult">125</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">std::string::find;</a><span class="tooltiptext code">template&lt;typename T>
void Find(benchmark::State&amp; 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(&quot;not find?&quot;);
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Здесь "победила дружба", у всех типов по колонке примерно одинаково.
Однако, Windows и Linux явно в разных весовых категориях.
Here, "friendship wins," with all types scoring roughly equally.
However, Windows and Linux are clearly in different weight classes.</span></span></td><td class="benchmarkresult">7.34</td><td class="benchmarkresult">7.76</td><td class="benchmarkresult">6.95</td><td class="benchmarkresult">40.2</td><td class="benchmarkresult">40.3</td><td class="benchmarkresult">40.8</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">std::string_view::find;</a><span class="tooltiptext code">template&lt;typename T>
void Find(benchmark::State&amp; 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(&quot;not find?&quot;);
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">7.81</td><td class="benchmarkresult">7.82</td><td class="benchmarkresult">7.39</td><td class="benchmarkresult">39.3</td><td class="benchmarkresult">39.8</td><td class="benchmarkresult">41.2</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">ssa::find;</a><span class="tooltiptext code">template&lt;typename T>
void Find(benchmark::State&amp; 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(&quot;not find?&quot;);
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">7.37</td><td class="benchmarkresult">7.82</td><td class="benchmarkresult">6.87</td><td class="benchmarkresult">18.7</td><td class="benchmarkresult">21.9</td><td class="benchmarkresult">40.6</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">stringa::find;</a><span class="tooltiptext code">template&lt;typename T>
void Find(benchmark::State&amp; 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(&quot;not find?&quot;);
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">8.14</td><td class="benchmarkresult">8.60</td><td class="benchmarkresult">7.21</td><td class="benchmarkresult">19.6</td><td class="benchmarkresult">29.4</td><td class="benchmarkresult">41.2</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">lstringa&lt;20>::find;</a><span class="tooltiptext code">template&lt;typename T>
void Find(benchmark::State&amp; 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(&quot;not find?&quot;);
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">6.94</td><td class="benchmarkresult">6.98</td><td class="benchmarkresult">6.52</td><td class="benchmarkresult">18.0</td><td class="benchmarkresult">24.4</td><td class="benchmarkresult">39.8</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">lstringa&lt;40>::find;</a><span class="tooltiptext code">template&lt;typename T>
void Find(benchmark::State&amp; 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(&quot;not find?&quot;);
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">6.93</td><td class="benchmarkresult">7.01</td><td class="benchmarkresult">6.49</td><td class="benchmarkresult">18.5</td><td class="benchmarkresult">23.1</td><td class="benchmarkresult">39.7</td></tr>
</tbody></table></div><script>bench_sets['Find 9 symbols text in end of 99 symbols text'] = {id:'bs14', tests:[
{name:'sz::string::find;',data:[95.9,96.5,87.9,94.8,117,125]},
{name:'std::string::find;',data:[7.34,7.76,6.95,40.2,40.3,40.8]},
{name:'std::string_view::find;',data:[7.81,7.82,7.39,39.3,39.8,41.2]},
{name:'ssa::find;',data:[7.37,7.82,6.87,18.7,21.9,40.6]},
{name:'stringa::find;',data:[8.14,8.60,7.21,19.6,29.4,41.2]},
{name:'lstringa<20>::find;',data:[6.94,6.98,6.52,18.0,24.4,39.8]},
{name:'lstringa<40>::find;',data:[6.93,7.01,6.49,18.5,23.1,39.7]}
]}</script>
<div class="benchset" id="bs15"><h4><a id="bs170792414351801782640" href="#bs170792414351801782640">#</a>&nbsp;Copy not literal Str with N symbols</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/15</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">5.78</td><td class="benchmarkresult">1.18</td><td class="benchmarkresult">5.01</td><td class="benchmarkresult">1.83</td><td class="benchmarkresult">5.18</td><td class="benchmarkresult">52.3</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/16</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Явно виден скачок, где заканчивается SSO и начинается аллокация.
Обратите внимание, что WASM - 32-битный, и там размер
SSO у std::string меньше, 10 символов + 0.
The jump where SSO ends and allocation begins is clearly visible.
Note that WASM is 32-bit, and the size of the SSO for std::string is
smaller, as far as I remember: 11 characters + 0.</span></span></td><td class="benchmarkresult">24.5</td><td class="benchmarkresult">1.16</td><td class="benchmarkresult">29.4</td><td class="benchmarkresult">78.7</td><td class="benchmarkresult">83.5</td><td class="benchmarkresult">53.0</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/23</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Дальше просто добавляется время на копирование байтов.
Then the time for copying bytes is simply added.</span></span></td><td class="benchmarkresult">28.5</td><td class="benchmarkresult">25.8</td><td class="benchmarkresult">28.9</td><td class="benchmarkresult">79.1</td><td class="benchmarkresult">82.0</td><td class="benchmarkresult">52.5</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/24</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">23.3</td><td class="benchmarkresult">24.8</td><td class="benchmarkresult">22.3</td><td class="benchmarkresult">80.3</td><td class="benchmarkresult">83.5</td><td class="benchmarkresult">51.6</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/32</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">23.2</td><td class="benchmarkresult">24.7</td><td class="benchmarkresult">21.5</td><td class="benchmarkresult">79.6</td><td class="benchmarkresult">89.4</td><td class="benchmarkresult">53.9</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/64</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">23.3</td><td class="benchmarkresult">26.2</td><td class="benchmarkresult">24.6</td><td class="benchmarkresult">80.7</td><td class="benchmarkresult">90.6</td><td class="benchmarkresult">54.4</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/128</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">24.9</td><td class="benchmarkresult">26.8</td><td class="benchmarkresult">24.2</td><td class="benchmarkresult">84.2</td><td class="benchmarkresult">90.0</td><td class="benchmarkresult">59.7</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/256</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">26.0</td><td class="benchmarkresult">27.5</td><td class="benchmarkresult">25.7</td><td class="benchmarkresult">87.3</td><td class="benchmarkresult">91.8</td><td class="benchmarkresult">73.8</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/512</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">29.4</td><td class="benchmarkresult">31.6</td><td class="benchmarkresult">28.5</td><td class="benchmarkresult">87.3</td><td class="benchmarkresult">96.2</td><td class="benchmarkresult">81.2</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/1024</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">47.7</td><td class="benchmarkresult">38.4</td><td class="benchmarkresult">33.4</td><td class="benchmarkresult">97.6</td><td class="benchmarkresult">102</td><td class="benchmarkresult">93.3</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/2048</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">125</td><td class="benchmarkresult">86.0</td><td class="benchmarkresult">122</td><td class="benchmarkresult">132</td><td class="benchmarkresult">132</td><td class="benchmarkresult">109</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/4096</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Чем длиннее строка, тем дольше создаётся копия.
The longer the string, the longer it takes to create a copy.</span></span></td><td class="benchmarkresult">152</td><td class="benchmarkresult">117</td><td class="benchmarkresult">157</td><td class="benchmarkresult">180</td><td class="benchmarkresult">184</td><td class="benchmarkresult">165</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/15</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Здесь stringa инициализируется не литералом,
а значит, должна сама хранить символы.
Here, stringa is not initialized with a literal,
meaning it must store characters itself.</span></span></td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.09</td><td class="benchmarkresult">4.04</td><td class="benchmarkresult">2.46</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/16</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Под WASM SSO у stringa составляет 15 символов. Кроме того,
собиралось без поддержки потоков, поэтому атомарный
инкремент заменён на обычный, судя по времени.
Under WASM, stringa has a 15-character SSO. Furthermore,
it was built without thread support, so the atomic
increment was replaced with a regular one, judging by the time.</span></span></td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.08</td><td class="benchmarkresult">4.07</td><td class="benchmarkresult">4.57</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/23</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">SSO в stringa до 23 символов, и даже 23
копируются быстрее, чем 15 в std::string.
SSO in stringa is up to 23 characters, and even 23
copies faster than 15 in std::string.</span></span></td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.09</td><td class="benchmarkresult">4.09</td><td class="benchmarkresult">4.54</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/24</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Всё, не влезаем в SSO, а значит, используем shared буфер.
Добавляется время на атомарный инкремент счётчика.
That's it, we're not using SSO, so we're using a shared buffer.
Time is added for the atomic counter increment.</span></span></td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.1</td><td class="benchmarkresult">18.8</td><td class="benchmarkresult">4.55</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/32</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">16.3</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.1</td><td class="benchmarkresult">18.6</td><td class="benchmarkresult">4.57</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/64</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">16.3</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.0</td><td class="benchmarkresult">18.6</td><td class="benchmarkresult">4.56</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/128</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.1</td><td class="benchmarkresult">18.6</td><td class="benchmarkresult">4.55</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/256</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.6</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.1</td><td class="benchmarkresult">18.7</td><td class="benchmarkresult">4.57</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/512</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.6</td><td class="benchmarkresult">16.3</td><td class="benchmarkresult">16.0</td><td class="benchmarkresult">19.1</td><td class="benchmarkresult">4.60</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/1024</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">16.3</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.1</td><td class="benchmarkresult">18.7</td><td class="benchmarkresult">4.57</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/2048</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.0</td><td class="benchmarkresult">18.7</td><td class="benchmarkresult">4.56</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/4096</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">И как видно, кроме инкремента нет накладных расходов,
время копирования не зависит от длины строки.
And as you can see, there are no overhead costs other than the
increment; copying time does not depend on the string length.</span></span></td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.7</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.1</td><td class="benchmarkresult">18.7</td><td class="benchmarkresult">4.57</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;16> copy{str_with_len_N};/15</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">lstringa<16> использует SSO до 23 символов.
А в WASM 32-битная архитектура, SSO до 19 символов.
lstringa<16> uses SSO up to 23 characters.
WASM has a 32-bit architecture, so SSO is up to 19 characters.</span></span></td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">4.06</td><td class="benchmarkresult">4.14</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;16> copy{str_with_len_N};/16</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">5.10</td><td class="benchmarkresult">5.35</td><td class="benchmarkresult">4.89</td><td class="benchmarkresult">4.56</td><td class="benchmarkresult">8.48</td><td class="benchmarkresult">16.9</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;16> copy{str_with_len_N};/23</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">5.16</td><td class="benchmarkresult">5.31</td><td class="benchmarkresult">4.91</td><td class="benchmarkresult">4.49</td><td class="benchmarkresult">8.54</td><td class="benchmarkresult">36.0</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;16> copy{str_with_len_N};/24</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">И после начинает вести себя при копировании, как std::string.
And then it starts to behave like std::string when copied.</span></span></td><td class="benchmarkresult">21.9</td><td class="benchmarkresult">21.8</td><td class="benchmarkresult">22.4</td><td class="benchmarkresult">76.6</td><td class="benchmarkresult">81.2</td><td class="benchmarkresult">37.0</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;16> copy{str_with_len_N};/32</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">22.1</td><td class="benchmarkresult">21.9</td><td class="benchmarkresult">22.5</td><td class="benchmarkresult">77.3</td><td class="benchmarkresult">84.1</td><td class="benchmarkresult">38.0</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;16> copy{str_with_len_N};/64</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">23.4</td><td class="benchmarkresult">23.1</td><td class="benchmarkresult">24.3</td><td class="benchmarkresult">79.3</td><td class="benchmarkresult">82.4</td><td class="benchmarkresult">38.3</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;16> copy{str_with_len_N};/128</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">24.5</td><td class="benchmarkresult">25.7</td><td class="benchmarkresult">33.8</td><td class="benchmarkresult">82.6</td><td class="benchmarkresult">85.6</td><td class="benchmarkresult">38.8</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;16> copy{str_with_len_N};/256</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">25.4</td><td class="benchmarkresult">24.8</td><td class="benchmarkresult">25.9</td><td class="benchmarkresult">83.7</td><td class="benchmarkresult">87.1</td><td class="benchmarkresult">62.4</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;16> copy{str_with_len_N};/512</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">28.6</td><td class="benchmarkresult">27.7</td><td class="benchmarkresult">34.8</td><td class="benchmarkresult">88.5</td><td class="benchmarkresult">90.7</td><td class="benchmarkresult">66.7</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;16> copy{str_with_len_N};/1024</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">98.9</td><td class="benchmarkresult">78.4</td><td class="benchmarkresult">99.7</td><td class="benchmarkresult">93.9</td><td class="benchmarkresult">101</td><td class="benchmarkresult">78.8</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;16> copy{str_with_len_N};/2048</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">103</td><td class="benchmarkresult">73.4</td><td class="benchmarkresult">110</td><td class="benchmarkresult">125</td><td class="benchmarkresult">135</td><td class="benchmarkresult">94.8</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;16> copy{str_with_len_N};/4096</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">122</td><td class="benchmarkresult">88.6</td><td class="benchmarkresult">129</td><td class="benchmarkresult">190</td><td class="benchmarkresult">196</td><td class="benchmarkresult">146</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;512> copy{str_with_len_N};/15</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">4.46</td><td class="benchmarkresult">4.06</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;512> copy{str_with_len_N};/16</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">5.00</td><td class="benchmarkresult">4.98</td><td class="benchmarkresult">4.22</td><td class="benchmarkresult">6.12</td><td class="benchmarkresult">8.96</td><td class="benchmarkresult">15.1</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;512> copy{str_with_len_N};/23</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">4.92</td><td class="benchmarkresult">5.01</td><td class="benchmarkresult">4.24</td><td class="benchmarkresult">5.29</td><td class="benchmarkresult">8.92</td><td class="benchmarkresult">15.1</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;512> copy{str_with_len_N};/24</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">29.6</td><td class="benchmarkresult">4.59</td><td class="benchmarkresult">4.26</td><td class="benchmarkresult">5.27</td><td class="benchmarkresult">9.07</td><td class="benchmarkresult">15.2</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;512> copy{str_with_len_N};/32</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">29.6</td><td class="benchmarkresult">4.64</td><td class="benchmarkresult">4.20</td><td class="benchmarkresult">8.14</td><td class="benchmarkresult">12.6</td><td class="benchmarkresult">16.9</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;512> copy{str_with_len_N};/64</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">30.2</td><td class="benchmarkresult">6.06</td><td class="benchmarkresult">5.67</td><td class="benchmarkresult">8.48</td><td class="benchmarkresult">12.5</td><td class="benchmarkresult">17.9</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;512> copy{str_with_len_N};/128</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">30.5</td><td class="benchmarkresult">6.63</td><td class="benchmarkresult">6.29</td><td class="benchmarkresult">8.58</td><td class="benchmarkresult">12.9</td><td class="benchmarkresult">18.2</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;512> copy{str_with_len_N};/256</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">21.7</td><td class="benchmarkresult">17.3</td><td class="benchmarkresult">7.98</td><td class="benchmarkresult">9.69</td><td class="benchmarkresult">14.0</td><td class="benchmarkresult">20.8</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;512> copy{str_with_len_N};/512</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Даже 512 символов копируются быстрее, чем
одна аллокация или атомарный инкремент.
Even 512 characters are copied faster than a single
allocation or atomic increment.</span></span></td><td class="benchmarkresult">24.7</td><td class="benchmarkresult">10.6</td><td class="benchmarkresult">10.2</td><td class="benchmarkresult">11.4</td><td class="benchmarkresult">15.7</td><td class="benchmarkresult">24.0</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;512> copy{str_with_len_N};/1024</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">А дальше уже как у всех.
And then it's like everyone else.</span></span></td><td class="benchmarkresult">96.9</td><td class="benchmarkresult">52.1</td><td class="benchmarkresult">96.5</td><td class="benchmarkresult">98.3</td><td class="benchmarkresult">95.0</td><td class="benchmarkresult">78.6</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;512> copy{str_with_len_N};/2048</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">106</td><td class="benchmarkresult">73.6</td><td class="benchmarkresult">103</td><td class="benchmarkresult">130</td><td class="benchmarkresult">128</td><td class="benchmarkresult">95.8</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa&lt;512> copy{str_with_len_N};/4096</a><span class="tooltiptext code">template&lt;typename T>
void CopyDynString(benchmark::State&amp; state) {
T x(state.range(0), &#39;a&#39;);
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}</span></span></td><td></td><td class="benchmarkresult">123</td><td class="benchmarkresult">90.1</td><td class="benchmarkresult">126</td><td class="benchmarkresult">188</td><td class="benchmarkresult">193</td><td class="benchmarkresult">146</td></tr>
</tbody></table></div><script>bench_sets['Copy not literal Str with N symbols'] = {id:'bs15', tests:[
{name:'std::string copy{str_with_len_N};/15',data:[5.78,1.18,5.01,1.83,5.18,52.3]},
{name:'std::string copy{str_with_len_N};/16',data:[24.5,1.16,29.4,78.7,83.5,53.0]},
{name:'std::string copy{str_with_len_N};/23',data:[28.5,25.8,28.9,79.1,82.0,52.5]},
{name:'std::string copy{str_with_len_N};/24',data:[23.3,24.8,22.3,80.3,83.5,51.6]},
{name:'std::string copy{str_with_len_N};/32',data:[23.2,24.7,21.5,79.6,89.4,53.9]},
{name:'std::string copy{str_with_len_N};/64',data:[23.3,26.2,24.6,80.7,90.6,54.4]},
{name:'std::string copy{str_with_len_N};/128',data:[24.9,26.8,24.2,84.2,90.0,59.7]},
{name:'std::string copy{str_with_len_N};/256',data:[26.0,27.5,25.7,87.3,91.8,73.8]},
{name:'std::string copy{str_with_len_N};/512',data:[29.4,31.6,28.5,87.3,96.2,81.2]},
{name:'std::string copy{str_with_len_N};/1024',data:[47.7,38.4,33.4,97.6,102,93.3]},
{name:'std::string copy{str_with_len_N};/2048',data:[125,86.0,122,132,132,109]},
{name:'std::string copy{str_with_len_N};/4096',data:[152,117,157,180,184,165]},
{name:'stringa copy{str_with_len_N};/15',data:[1.12,1.13,1.13,1.09,4.04,2.46]},
{name:'stringa copy{str_with_len_N};/16',data:[1.13,1.13,1.15,1.08,4.07,4.57]},
{name:'stringa copy{str_with_len_N};/23',data:[1.12,1.13,1.13,1.09,4.09,4.54]},
{name:'stringa copy{str_with_len_N};/24',data:[16.4,16.5,16.4,16.1,18.8,4.55]},
{name:'stringa copy{str_with_len_N};/32',data:[16.3,16.5,16.4,16.1,18.6,4.57]},
{name:'stringa copy{str_with_len_N};/64',data:[16.3,16.5,16.5,16.0,18.6,4.56]},
{name:'stringa copy{str_with_len_N};/128',data:[16.4,16.5,16.4,16.1,18.6,4.55]},
{name:'stringa copy{str_with_len_N};/256',data:[16.4,16.6,16.5,16.1,18.7,4.57]},
{name:'stringa copy{str_with_len_N};/512',data:[16.4,16.6,16.3,16.0,19.1,4.60]},
{name:'stringa copy{str_with_len_N};/1024',data:[16.3,16.5,16.4,16.1,18.7,4.57]},
{name:'stringa copy{str_with_len_N};/2048',data:[16.4,16.5,16.4,16.0,18.7,4.56]},
{name:'stringa copy{str_with_len_N};/4096',data:[16.4,16.7,16.5,16.1,18.7,4.57]},
{name:'lstringa<16> copy{str_with_len_N};/15',data:[1.14,1.12,1.15,1.12,4.06,4.14]},
{name:'lstringa<16> copy{str_with_len_N};/16',data:[5.10,5.35,4.89,4.56,8.48,16.9]},
{name:'lstringa<16> copy{str_with_len_N};/23',data:[5.16,5.31,4.91,4.49,8.54,36.0]},
{name:'lstringa<16> copy{str_with_len_N};/24',data:[21.9,21.8,22.4,76.6,81.2,37.0]},
{name:'lstringa<16> copy{str_with_len_N};/32',data:[22.1,21.9,22.5,77.3,84.1,38.0]},
{name:'lstringa<16> copy{str_with_len_N};/64',data:[23.4,23.1,24.3,79.3,82.4,38.3]},
{name:'lstringa<16> copy{str_with_len_N};/128',data:[24.5,25.7,33.8,82.6,85.6,38.8]},
{name:'lstringa<16> copy{str_with_len_N};/256',data:[25.4,24.8,25.9,83.7,87.1,62.4]},
{name:'lstringa<16> copy{str_with_len_N};/512',data:[28.6,27.7,34.8,88.5,90.7,66.7]},
{name:'lstringa<16> copy{str_with_len_N};/1024',data:[98.9,78.4,99.7,93.9,101,78.8]},
{name:'lstringa<16> copy{str_with_len_N};/2048',data:[103,73.4,110,125,135,94.8]},
{name:'lstringa<16> copy{str_with_len_N};/4096',data:[122,88.6,129,190,196,146]},
{name:'lstringa<512> copy{str_with_len_N};/15',data:[1.13,1.13,1.15,1.14,4.46,4.06]},
{name:'lstringa<512> copy{str_with_len_N};/16',data:[5.00,4.98,4.22,6.12,8.96,15.1]},
{name:'lstringa<512> copy{str_with_len_N};/23',data:[4.92,5.01,4.24,5.29,8.92,15.1]},
{name:'lstringa<512> copy{str_with_len_N};/24',data:[29.6,4.59,4.26,5.27,9.07,15.2]},
{name:'lstringa<512> copy{str_with_len_N};/32',data:[29.6,4.64,4.20,8.14,12.6,16.9]},
{name:'lstringa<512> copy{str_with_len_N};/64',data:[30.2,6.06,5.67,8.48,12.5,17.9]},
{name:'lstringa<512> copy{str_with_len_N};/128',data:[30.5,6.63,6.29,8.58,12.9,18.2]},
{name:'lstringa<512> copy{str_with_len_N};/256',data:[21.7,17.3,7.98,9.69,14.0,20.8]},
{name:'lstringa<512> copy{str_with_len_N};/512',data:[24.7,10.6,10.2,11.4,15.7,24.0]},
{name:'lstringa<512> copy{str_with_len_N};/1024',data:[96.9,52.1,96.5,98.3,95.0,78.6]},
{name:'lstringa<512> copy{str_with_len_N};/2048',data:[106,73.6,103,130,128,95.8]},
{name:'lstringa<512> copy{str_with_len_N};/4096',data:[123,90.1,126,188,193,146]}
]}</script>
<div class="benchset" id="bs16"><h4><a id="bs94756718925776995960" href="#bs94756718925776995960">#</a>&nbsp;Convert to int &#39;1234567&#39;</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L816">std::string s = &quot;123456789&quot;; int res = std::strtol(s.c_str(), 0, 10);</a><span class="tooltiptext code">void ToIntStr10(benchmark::State&amp; state, const std::string&amp; s, int c) {
for (auto _: state) {
int res = std::strtol(s.c_str(), nullptr, 10);
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">В simstr для конвертации в число достаточно куска строки,
нет нужды в null терминированности. Ближайший аналог такого
поведения "std::from_chars", но он к сожалению очень ограничен
по возможностям. Здесь я попытался произвести тесты, близкие по
логике к работе std::from_chars
In simstr, a string fragment is sufficient for conversion to a number;
there's no need for null termination. The closest analog to this behavior
is "std::from_chars," but unfortunately, it is very limited in its capabilities.
Here, I attempted to run tests that are similar in logic to std::from_chars.</span></span></td><td class="benchmarkresult">26.9</td><td class="benchmarkresult">27.4</td><td class="benchmarkresult">27.9</td><td class="benchmarkresult">31.4</td><td class="benchmarkresult">31.9</td><td class="benchmarkresult">91.7</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L855">std::string_view s = &quot;123456789&quot;; std::from_chars(s.data(), s.data() + s.size(), res, 10);</a><span class="tooltiptext code">void ToIntFromChars10(benchmark::State&amp; state, const std::string_view&amp; 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(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">from_chars требует точного указания основания счисления,
не допускает знаков плюс, пробелов, префиксов 0x и т.п.
from_chars requires an exact radix specification and does not allow plus
signs, spaces, 0x prefixes, etc.</span></span></td><td class="benchmarkresult">14.9</td><td class="benchmarkresult">17.5</td><td class="benchmarkresult">12.5</td><td class="benchmarkresult">12.6</td><td class="benchmarkresult">11.8</td><td class="benchmarkresult">0.739</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L883">stringa s = &quot;123456789&quot;; int res = s.to_int&lt;int, true, 10, false></a><span class="tooltiptext code">template&lt;typename T>
void ToIntSimStr10(benchmark::State&amp; state, T t, int c) {
for (auto _: state) {
int res = t. template to_int&lt;int, true, 10, false, false>().value;
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Здесь для to_int заданы такие же ограничения - проверять переполнение,
десятичная система, без лидирующих пробелов и знака плюс
Here, to_int has the same restrictions: check for overflow,
decimal system, no leading spaces, and no plus sign.</span></span></td><td class="benchmarkresult">9.36</td><td class="benchmarkresult">9.48</td><td class="benchmarkresult">16.8</td><td class="benchmarkresult">13.7</td><td class="benchmarkresult">16.8</td><td class="benchmarkresult">20.4</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L883">ssa s = &quot;123456789&quot;; int res = s.to_int&lt;int, true, 10, false></a><span class="tooltiptext code">template&lt;typename T>
void ToIntSimStr10(benchmark::State&amp; state, T t, int c) {
for (auto _: state) {
int res = t. template to_int&lt;int, true, 10, false, false>().value;
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
}</span></span></td><td></td><td class="benchmarkresult">9.52</td><td class="benchmarkresult">9.76</td><td class="benchmarkresult">7.54</td><td class="benchmarkresult">9.40</td><td class="benchmarkresult">15.6</td><td class="benchmarkresult">16.2</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L883">lstringa&lt;20> s = &quot;123456789&quot;; int res = s.to_int&lt;int, true, 10, false></a><span class="tooltiptext code">template&lt;typename T>
void ToIntSimStr10(benchmark::State&amp; state, T t, int c) {
for (auto _: state) {
int res = t. template to_int&lt;int, true, 10, false, false>().value;
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
}</span></span></td><td></td><td class="benchmarkresult">9.61</td><td class="benchmarkresult">9.51</td><td class="benchmarkresult">8.43</td><td class="benchmarkresult">13.4</td><td class="benchmarkresult">14.8</td><td class="benchmarkresult">16.1</td></tr>
</tbody></table></div><script>bench_sets['Convert to int \'1234567\''] = {id:'bs16', tests:[
{name:'std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);',data:[26.9,27.4,27.9,31.4,31.9,91.7]},
{name:'std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);',data:[14.9,17.5,12.5,12.6,11.8,0.739]},
{name:'stringa s = "123456789"; int res = s.to_int<int, true, 10, false>',data:[9.36,9.48,16.8,13.7,16.8,20.4]},
{name:'ssa s = "123456789"; int res = s.to_int<int, true, 10, false>',data:[9.52,9.76,7.54,9.40,15.6,16.2]},
{name:'lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>',data:[9.61,9.51,8.43,13.4,14.8,16.1]}
]}</script>
<div class="benchset" id="bs17"><h4><a id="bs182426078870126042750" href="#bs182426078870126042750">#</a>&nbsp;Convert to unsigned &#39;abcDef&#39;</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L829">std::string s = &quot;abcDef&quot;; int res = std::strtol(s.c_str(), 0, 16);</a><span class="tooltiptext code">void ToIntStr16(benchmark::State&amp; state, const std::string&amp; s, int c) {
for (auto _: state) {
int res = std::strtol(s.c_str(), nullptr, 16);
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Всё то же, только для 16ричной системы
Everything is the same, only for the hexadecimal system</span></span></td><td class="benchmarkresult">24.5</td><td class="benchmarkresult">24.4</td><td class="benchmarkresult">23.9</td><td class="benchmarkresult">33.6</td><td class="benchmarkresult">35.5</td><td class="benchmarkresult">67.2</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L869">std::string_view s = &quot;abcDef&quot;; std::from_chars(s.data(), s.data() + s.size(), res, 16);</a><span class="tooltiptext code">void ToIntFromChars16(benchmark::State&amp; state, const std::string_view&amp; 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(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
}
}</span></span></td><td></td><td class="benchmarkresult">9.59</td><td class="benchmarkresult">22.0</td><td class="benchmarkresult">9.15</td><td class="benchmarkresult">8.50</td><td class="benchmarkresult">8.96</td><td class="benchmarkresult">18.3</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L898">stringa s = &quot;abcDef&quot;; int res = s.to_int&lt;int, true, 16, false></a><span class="tooltiptext code">template&lt;typename T>
void ToIntSimStr16(benchmark::State&amp; state, T t, int c) {
for (auto _: state) {
int res = t. template to_int&lt;int, true, 16, false, false>().value;
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
}</span></span></td><td></td><td class="benchmarkresult">8.04</td><td class="benchmarkresult">8.28</td><td class="benchmarkresult">16.2</td><td class="benchmarkresult">13.7</td><td class="benchmarkresult">14.5</td><td class="benchmarkresult">17.2</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L898">ssa s = &quot;abcDef&quot;; int res = s.to_int&lt;int, true, 16, false></a><span class="tooltiptext code">template&lt;typename T>
void ToIntSimStr16(benchmark::State&amp; state, T t, int c) {
for (auto _: state) {
int res = t. template to_int&lt;int, true, 16, false, false>().value;
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
}</span></span></td><td></td><td class="benchmarkresult">7.57</td><td class="benchmarkresult">7.65</td><td class="benchmarkresult">6.48</td><td class="benchmarkresult">7.50</td><td class="benchmarkresult">13.3</td><td class="benchmarkresult">16.7</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L898">lstringa&lt;20> s = &quot;abcDef&quot;; int res = s.to_int&lt;int, true, 16, false></a><span class="tooltiptext code">template&lt;typename T>
void ToIntSimStr16(benchmark::State&amp; state, T t, int c) {
for (auto _: state) {
int res = t. template to_int&lt;int, true, 16, false, false>().value;
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
}</span></span></td><td></td><td class="benchmarkresult">7.82</td><td class="benchmarkresult">7.84</td><td class="benchmarkresult">6.42</td><td class="benchmarkresult">12.6</td><td class="benchmarkresult">12.7</td><td class="benchmarkresult">16.1</td></tr>
</tbody></table></div><script>bench_sets['Convert to unsigned \'abcDef\''] = {id:'bs17', tests:[
{name:'std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);',data:[24.5,24.4,23.9,33.6,35.5,67.2]},
{name:'std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);',data:[9.59,22.0,9.15,8.50,8.96,18.3]},
{name:'stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>',data:[8.04,8.28,16.2,13.7,14.5,17.2]},
{name:'ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>',data:[7.57,7.65,6.48,7.50,13.3,16.7]},
{name:'lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>',data:[7.82,7.84,6.42,12.6,12.7,16.1]}
]}</script>
<div class="benchset" id="bs18"><h4><a id="bs52606100125109966680" href="#bs52606100125109966680">#</a>&nbsp;Convert to int &#39; 1234567&#39;</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L842">std::string s = &quot; 123456789&quot;; int res = std::strtol(s.c_str(), 0, 0);</a><span class="tooltiptext code">void ToIntStr0(benchmark::State&amp; state, const std::string&amp; s, int c) {
for (auto _: state) {
int res = std::strtol(s.c_str(), nullptr, 0);
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">А здесь уже парсинг произвольного числа.
And here we have parsing of an arbitrary number.</span></span></td><td class="benchmarkresult">29.2</td><td class="benchmarkresult">29.4</td><td class="benchmarkresult">29.1</td><td class="benchmarkresult">43.6</td><td class="benchmarkresult">45.6</td><td class="benchmarkresult">97.3</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L913">stringa s = &quot; 123456789&quot;; int res = s.to_int&lt;int>; // Check overflow</a><span class="tooltiptext code">template&lt;typename T>
void ToIntSimStr0(benchmark::State&amp; state, T t, int c) {
for (auto _: state) {
int res = t. template to_int&lt;int>().value;
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
}</span></span></td><td></td><td class="benchmarkresult">11.0</td><td class="benchmarkresult">11.4</td><td class="benchmarkresult">23.8</td><td class="benchmarkresult">17.3</td><td class="benchmarkresult">22.4</td><td class="benchmarkresult">13.7</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L928">ssa s = &quot; 123456789&quot;; int res = s.to_int&lt;int, false>; // No check overflow</a><span class="tooltiptext code">void ToIntNoOverflow(benchmark::State&amp; state, ssa t, int c) {
for (auto _: state) {
int res = t.to_int&lt;int, false>().value;
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
}</span></span></td><td></td><td class="benchmarkresult">13.3</td><td class="benchmarkresult">13.2</td><td class="benchmarkresult">11.0</td><td class="benchmarkresult">12.9</td><td class="benchmarkresult">19.1</td><td class="benchmarkresult">15.0</td></tr>
</tbody></table></div><script>bench_sets['Convert to int \' 1234567\''] = {id:'bs18', tests:[
{name:'std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);',data:[29.2,29.4,29.1,43.6,45.6,97.3]},
{name:'stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow',data:[11.0,11.4,23.8,17.3,22.4,13.7]},
{name:'ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow',data:[13.3,13.2,11.0,12.9,19.1,15.0]}
]}</script>
<div class="benchset" id="bs19"><h4><a id="bs182348477702821075660" href="#bs182348477702821075660">#</a>&nbsp;Convert to double &#39;1234.567e10&#39;</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L958">std::string s = &quot;1234.567e10&quot;; double res = std::strtod(s.c_str(), nullptr);</a><span class="tooltiptext code">void ToDoubleStr(benchmark::State&amp; state, const std::string&amp; s, double c) {
for (auto _: state) {
char* ptr = nullptr;
double res = std::strtod(s.c_str(), &amp;ptr);
if (ptr == s.c_str()) {
state.SkipWithError(&quot;not equal&quot;);
}
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
}
}</span></span></td><td></td><td class="benchmarkresult">66.6</td><td class="benchmarkresult">65.8</td><td class="benchmarkresult">66.3</td><td class="benchmarkresult">100</td><td class="benchmarkresult">103</td><td class="benchmarkresult">298</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L975">std::string_view s = &quot;1234.567e10&quot;; std::from_chars(s.data(), s.data() + s.size(), res);</a><span class="tooltiptext code">template&lt;typename K = char>
void ToDoubleFromChars(benchmark::State&amp; state, const std::string_view&amp; s, double c) {
for (auto _: state) {
double res = 0;
if constexpr (requires { std::from_chars(std::declval&lt;K*>(), std::declval&lt;K*>(), std::declval&lt;double&amp;>()); }) {
if (std::from_chars((const K*)s.data(), (const K*)s.data() + s.size(), res).ec != std::errc{}) {
state.SkipWithError(&quot;not equal&quot;);
}
} else {
state.SkipWithError(&quot;not implemented&quot;);
}
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
}
}</span></span></td><td></td><td class="benchmarkresult">24.5</td><td class="benchmarkresult">Not impl</td><td class="benchmarkresult">24.4</td><td class="benchmarkresult">58.7</td><td class="benchmarkresult">82.7</td><td class="benchmarkresult">108</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L996">ssa s = &quot;1234.567e10&quot;; double res = *s.to_double()</a><span class="tooltiptext code">template&lt;typename T>
void ToDoubleSimStr(benchmark::State&amp; state, T t, double c) {
for (auto _: state) {
auto r = t.template to_double&lt;false>();
if (!r) {
state.SkipWithError(&quot;not equal&quot;);
}
double res = *r;
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
}</span></span></td><td></td><td class="benchmarkresult">26.8</td><td class="benchmarkresult">34.8</td><td class="benchmarkresult">24.5</td><td class="benchmarkresult">36.7</td><td class="benchmarkresult">37.7</td><td class="benchmarkresult">42.2</td></tr>
</tbody></table></div><script>bench_sets['Convert to double \'1234.567e10\''] = {id:'bs19', tests:[
{name:'std::string s = "1234.567e10"; double res = std::strtod(s.c_str(), nullptr);',data:[66.6,65.8,66.3,100,103,298]},
{name:'std::string_view s = "1234.567e10"; std::from_chars(s.data(), s.data() + s.size(), res);',data:[24.5,NaN,24.4,58.7,82.7,108]},
{name:'ssa s = "1234.567e10"; double res = *s.to_double()',data:[26.8,34.8,24.5,36.7,37.7,42.2]}
]}</script>
<div class="benchset" id="bs20"><h4><a id="bs96505608161678391610" href="#bs96505608161678391610">#</a>&nbsp;Append const literal of 16 bytes 64 times, 1024 total length</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1020">std::stringstream str; ... str &lt;&lt; &quot;abbaabbaabbaabba&quot;;</a><span class="tooltiptext code">void AppendStreamConstLiteral(benchmark::State&amp; state) {
for (auto _: state) {
std::string result;
std::stringstream str;
for (size_t c = 0; c &lt; 64; c++) {
str &lt;&lt; TEXT_16;
}
result = str.str();
#ifdef CHECK_RESULT
if (result.size() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(str);
}
}</span></span></td><td></td><td class="benchmarkresult">1424</td><td class="benchmarkresult">2080</td><td class="benchmarkresult">1411</td><td class="benchmarkresult">5118</td><td class="benchmarkresult">5722</td><td class="benchmarkresult">6499</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1039">std::string str; ... str += &quot;abbaabbaabbaabba&quot;;</a><span class="tooltiptext code">void AppendStdStringConstLiteral(benchmark::State&amp; state) {
for (auto _: state) {
std::string result;
for (size_t c = 0; c &lt; 64; c++) {
result += TEXT_16;
}
#ifdef CHECK_RESULT
if (result.size() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
}
}</span></span></td><td></td><td class="benchmarkresult">445</td><td class="benchmarkresult">416</td><td class="benchmarkresult">380</td><td class="benchmarkresult">1073</td><td class="benchmarkresult">1306</td><td class="benchmarkresult">815</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1055">lstringa&lt;8> str; ... str += &quot;abbaabbaabbaabba&quot;;</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstringConstLiteral(benchmark::State&amp; state) {
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 64; c++) {
result += TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
}
}</span></span></td><td></td><td class="benchmarkresult">388</td><td class="benchmarkresult">362</td><td class="benchmarkresult">364</td><td class="benchmarkresult">767</td><td class="benchmarkresult">914</td><td class="benchmarkresult">794</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1055">lstringa&lt;128> str; ... str += &quot;abbaabbaabbaabba&quot;;</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstringConstLiteral(benchmark::State&amp; state) {
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 64; c++) {
result += TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Чем больше внутренний буфер, тем меньше раз требуется
аллокация, тем быстрее результат.
The larger the internal buffer, the fewer allocations are
required, and the faster the result.</span></span></td><td class="benchmarkresult">276</td><td class="benchmarkresult">245</td><td class="benchmarkresult">271</td><td class="benchmarkresult">390</td><td class="benchmarkresult">542</td><td class="benchmarkresult">620</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1055">lstringa&lt;512> str; ... str += &quot;abbaabbaabbaabba&quot;;</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstringConstLiteral(benchmark::State&amp; state) {
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 64; c++) {
result += TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
}
}</span></span></td><td></td><td class="benchmarkresult">219</td><td class="benchmarkresult">217</td><td class="benchmarkresult">229</td><td class="benchmarkresult">239</td><td class="benchmarkresult">364</td><td class="benchmarkresult">401</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1055">lstringa&lt;1024> str; ... str += &quot;abbaabbaabbaabba&quot;;</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstringConstLiteral(benchmark::State&amp; state) {
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 64; c++) {
result += TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
}
}</span></span></td><td></td><td class="benchmarkresult">137</td><td class="benchmarkresult">136</td><td class="benchmarkresult">144</td><td class="benchmarkresult">158</td><td class="benchmarkresult">230</td><td class="benchmarkresult">335</td></tr>
</tbody></table></div><script>bench_sets['Append const literal of 16 bytes 64 times, 1024 total length'] = {id:'bs20', tests:[
{name:'std::stringstream str; ... str << "abbaabbaabbaabba";',data:[1424,2080,1411,5118,5722,6499]},
{name:'std::string str; ... str += "abbaabbaabbaabba";',data:[445,416,380,1073,1306,815]},
{name:'lstringa<8> str; ... str += "abbaabbaabbaabba";',data:[388,362,364,767,914,794]},
{name:'lstringa<128> str; ... str += "abbaabbaabbaabba";',data:[276,245,271,390,542,620]},
{name:'lstringa<512> str; ... str += "abbaabbaabbaabba";',data:[219,217,229,239,364,401]},
{name:'lstringa<1024> str; ... str += "abbaabbaabbaabba";',data:[137,136,144,158,230,335]}
]}</script>
<div class="benchset" id="bs21"><h4><a id="bs36931044816721597850" href="#bs36931044816721597850">#</a>&nbsp;Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1080">std::stringstream str; ... str &lt;&lt; str_var &lt;&lt; &quot;abbaabbaabbaabba&quot;;</a><span class="tooltiptext code">void AppendStreamStrConstLiteral(benchmark::State&amp; state) {
std::string s1 = TEXT_16;
for (auto _: state) {
std::string result;
std::stringstream s;
for (size_t c = 0; c &lt; 32; c++) {
s &lt;&lt; s1 &lt;&lt; TEXT_16;
}
result = s.str();
#ifdef CHECK_RESULT
if (result.size() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
}
}</span></span></td><td></td><td class="benchmarkresult">1426</td><td class="benchmarkresult">2037</td><td class="benchmarkresult">1391</td><td class="benchmarkresult">4657</td><td class="benchmarkresult">5665</td><td class="benchmarkresult">7163</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1100">std::string str; ... str += str_var + &quot;abbaabbaabbaabba&quot;;</a><span class="tooltiptext code">void AppendStdStrStrConstLiteral(benchmark::State&amp; state) {
std::string p1 = TEXT_16;
for (auto _: state) {
std::string result;
for (size_t c = 0; c &lt; 32; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.size() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
}</span></span></td><td></td><td class="benchmarkresult">1288</td><td class="benchmarkresult">1253</td><td class="benchmarkresult">1161</td><td class="benchmarkresult">3774</td><td class="benchmarkresult">3902</td><td class="benchmarkresult">2186</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1118">lstringa&lt;8> str; ... str += str_var + &quot;abbaabbaabbaabba&quot;;</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstringStrConstLiteral(benchmark::State&amp; state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 32; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
}</span></span></td><td></td><td class="benchmarkresult">426</td><td class="benchmarkresult">401</td><td class="benchmarkresult">443</td><td class="benchmarkresult">716</td><td class="benchmarkresult">822</td><td class="benchmarkresult">890</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1118">lstringa&lt;128> str; ... str += str_var + &quot;abbaabbaabbaabba&quot;;</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstringStrConstLiteral(benchmark::State&amp; state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 32; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
}</span></span></td><td></td><td class="benchmarkresult">340</td><td class="benchmarkresult">335</td><td class="benchmarkresult">368</td><td class="benchmarkresult">442</td><td class="benchmarkresult">535</td><td class="benchmarkresult">864</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1118">lstringa&lt;512> str; ... str += str_var + &quot;abbaabbaabbaabba&quot;;</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstringStrConstLiteral(benchmark::State&amp; state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 32; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
}</span></span></td><td></td><td class="benchmarkresult">313</td><td class="benchmarkresult">291</td><td class="benchmarkresult">348</td><td class="benchmarkresult">303</td><td class="benchmarkresult">377</td><td class="benchmarkresult">722</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1118">lstringa&lt;1024> str; ... str += str_var + &quot;abbaabbaabbaabba&quot;;</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstringStrConstLiteral(benchmark::State&amp; state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 32; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
}</span></span></td><td></td><td class="benchmarkresult">217</td><td class="benchmarkresult">214</td><td class="benchmarkresult">214</td><td class="benchmarkresult">188</td><td class="benchmarkresult">286</td><td class="benchmarkresult">639</td></tr>
</tbody></table></div><script>bench_sets['Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length'] = {id:'bs21', tests:[
{name:'std::stringstream str; ... str << str_var << "abbaabbaabbaabba";',data:[1426,2037,1391,4657,5665,7163]},
{name:'std::string str; ... str += str_var + "abbaabbaabbaabba";',data:[1288,1253,1161,3774,3902,2186]},
{name:'lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";',data:[426,401,443,716,822,890]},
{name:'lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";',data:[340,335,368,442,535,864]},
{name:'lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";',data:[313,291,348,303,377,722]},
{name:'lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";',data:[217,214,214,188,286,639]}
]}</script>
<div class="benchset" id="bs22"><h4><a id="bs8293767858383349360" href="#bs8293767858383349360">#</a>&nbsp;Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1146">std::stringstream str; ... str &lt;&lt; str_var &lt;&lt; &quot;abbaabbaabbaabba&quot;; 2048 times</a><span class="tooltiptext code">void AppendStreamStrConstLiteralBig(benchmark::State&amp; state) {
std::string s1 = TEXT_16;
for (auto _: state) {
std::string result;
std::stringstream s;
for (size_t c = 0; c &lt; 2048; c++) {
s &lt;&lt; s1 &lt;&lt; TEXT_16;
}
result = s.str();
#ifdef CHECK_RESULT
if (result.size() != 1024 * 64) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
}
}</span></span></td><td></td><td class="benchmarkresult">75809</td><td class="benchmarkresult">159733</td><td class="benchmarkresult">75407</td><td class="benchmarkresult">221584</td><td class="benchmarkresult">295560</td><td class="benchmarkresult">348509</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1166">std::string str; ... str += str_var + &quot;abbaabbaabbaabba&quot;; 2048 times</a><span class="tooltiptext code">void AppendStdStrStrConstLiteralBig(benchmark::State&amp; state) {
std::string p1 = TEXT_16;
for (auto _: state) {
std::string result;
for (size_t c = 0; c &lt; 2048; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.size() != 1024 * 64) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
}</span></span></td><td></td><td class="benchmarkresult">73098</td><td class="benchmarkresult">104710</td><td class="benchmarkresult">67303</td><td class="benchmarkresult">183793</td><td class="benchmarkresult">199734</td><td class="benchmarkresult">120123</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1184">lstringa&lt;8> str; ... str += str_var + &quot;abbaabbaabbaabba&quot;; 2048 times</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstringStrConstLiteralBig(benchmark::State&amp; state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 2048; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024 * 64) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
}</span></span></td><td></td><td class="benchmarkresult">19767</td><td class="benchmarkresult">49815</td><td class="benchmarkresult">20392</td><td class="benchmarkresult">19687</td><td class="benchmarkresult">25221</td><td class="benchmarkresult">44146</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1184">lstringa&lt;128> str; ... str += str_var + &quot;abbaabbaabbaabba&quot;; 2048 times</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstringStrConstLiteralBig(benchmark::State&amp; state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 2048; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024 * 64) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
}</span></span></td><td></td><td class="benchmarkresult">17379</td><td class="benchmarkresult">27270</td><td class="benchmarkresult">17950</td><td class="benchmarkresult">16880</td><td class="benchmarkresult">23191</td><td class="benchmarkresult">44572</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1184">lstringa&lt;512> str; ... str += str_var + &quot;abbaabbaabbaabba&quot;; 2048 times</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstringStrConstLiteralBig(benchmark::State&amp; state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 2048; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024 * 64) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
}</span></span></td><td></td><td class="benchmarkresult">16895</td><td class="benchmarkresult">16860</td><td class="benchmarkresult">17908</td><td class="benchmarkresult">17061</td><td class="benchmarkresult">21887</td><td class="benchmarkresult">44298</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1184">lstringa&lt;1024> str; ... str += str_var + &quot;abbaabbaabbaabba&quot;; 2048 times</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstringStrConstLiteralBig(benchmark::State&amp; state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 2048; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024 * 64) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
}</span></span></td><td></td><td class="benchmarkresult">17082</td><td class="benchmarkresult">16899</td><td class="benchmarkresult">17735</td><td class="benchmarkresult">16444</td><td class="benchmarkresult">22577</td><td class="benchmarkresult">44327</td></tr>
</tbody></table></div><script>bench_sets['Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length'] = {id:'bs22', tests:[
{name:'std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times',data:[75809,159733,75407,221584,295560,348509]},
{name:'std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[73098,104710,67303,183793,199734,120123]},
{name:'lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[19767,49815,20392,19687,25221,44146]},
{name:'lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[17379,27270,17950,16880,23191,44572]},
{name:'lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[16895,16860,17908,17061,21887,44298]},
{name:'lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[17082,16899,17735,16444,22577,44327]}
]}</script>
<div class="benchset" id="bs23"><h4><a id="bs66949588770596833730" href="#bs66949588770596833730">#</a>&nbsp;Append 2 string of 16 bytes 32 times, 1024 total length</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1211">std::stringstream str; ... str &lt;&lt; str_var1 &lt;&lt; str_var2;</a><span class="tooltiptext code">void AppendStream2String(benchmark::State&amp; 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 &lt; 32; c++) {
s &lt;&lt; s1 &lt;&lt; s2;
}
result = s.str();
#ifdef CHECK_RESULT
if (result.size() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
benchmark::DoNotOptimize(s2);
}
}</span></span></td><td></td><td class="benchmarkresult">1469</td><td class="benchmarkresult">2073</td><td class="benchmarkresult">1397</td><td class="benchmarkresult">4403</td><td class="benchmarkresult">5538</td><td class="benchmarkresult">7317</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1233">std::string str; ... str += str_var1 + str_var2;</a><span class="tooltiptext code">void AppendStdStr2String(benchmark::State&amp; state) {
std::string s1 = TEXT_16;
std::string s2 = TEXT_16;
for (auto _: state) {
std::string result;
for (size_t c = 0; c &lt; 32; c++) {
result += s1 + s2;
}
#ifdef CHECK_RESULT
if (result.size() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
benchmark::DoNotOptimize(s2);
}
}</span></span></td><td></td><td class="benchmarkresult">1415</td><td class="benchmarkresult">1492</td><td class="benchmarkresult">1344</td><td class="benchmarkresult">3893</td><td class="benchmarkresult">4019</td><td class="benchmarkresult">2607</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1254">lstringa&lt;16> str; ... str += str_var1 + str_var2;</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstring2String(benchmark::State&amp; state) {
stra s1 = TEXT_16;
stra s2 = TEXT_16;
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 32; c++) {
result += s1 + s2;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
benchmark::DoNotOptimize(s2);
}
}</span></span></td><td></td><td class="benchmarkresult">527</td><td class="benchmarkresult">476</td><td class="benchmarkresult">547</td><td class="benchmarkresult">794</td><td class="benchmarkresult">900</td><td class="benchmarkresult">1132</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1254">lstringa&lt;128> str; ... str += str_var1 + str_var2;</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstring2String(benchmark::State&amp; state) {
stra s1 = TEXT_16;
stra s2 = TEXT_16;
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 32; c++) {
result += s1 + s2;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
benchmark::DoNotOptimize(s2);
}
}</span></span></td><td></td><td class="benchmarkresult">465</td><td class="benchmarkresult">448</td><td class="benchmarkresult">454</td><td class="benchmarkresult">527</td><td class="benchmarkresult">641</td><td class="benchmarkresult">1062</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1254">lstringa&lt;512> str; ... str += str_var1 + str_var2;</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstring2String(benchmark::State&amp; state) {
stra s1 = TEXT_16;
stra s2 = TEXT_16;
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 32; c++) {
result += s1 + s2;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
benchmark::DoNotOptimize(s2);
}
}</span></span></td><td></td><td class="benchmarkresult">408</td><td class="benchmarkresult">379</td><td class="benchmarkresult">422</td><td class="benchmarkresult">381</td><td class="benchmarkresult">482</td><td class="benchmarkresult">914</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1254">lstringa&lt;1024> str; ... str += str_var1 + str_var2;</a><span class="tooltiptext code">template&lt;unsigned N>
void AppendLstring2String(benchmark::State&amp; state) {
stra s1 = TEXT_16;
stra s2 = TEXT_16;
for (auto _: state) {
lstringa&lt;N> result;
for (size_t c = 0; c &lt; 32; c++) {
result += s1 + s2;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
benchmark::DoNotOptimize(s2);
}
}</span></span></td><td></td><td class="benchmarkresult">309</td><td class="benchmarkresult">298</td><td class="benchmarkresult">310</td><td class="benchmarkresult">297</td><td class="benchmarkresult">365</td><td class="benchmarkresult">829</td></tr>
</tbody></table></div><script>bench_sets['Append 2 string of 16 bytes 32 times, 1024 total length'] = {id:'bs23', tests:[
{name:'std::stringstream str; ... str << str_var1 << str_var2;',data:[1469,2073,1397,4403,5538,7317]},
{name:'std::string str; ... str += str_var1 + str_var2;',data:[1415,1492,1344,3893,4019,2607]},
{name:'lstringa<16> str; ... str += str_var1 + str_var2;',data:[527,476,547,794,900,1132]},
{name:'lstringa<128> str; ... str += str_var1 + str_var2;',data:[465,448,454,527,641,1062]},
{name:'lstringa<512> str; ... str += str_var1 + str_var2;',data:[408,379,422,381,482,914]},
{name:'lstringa<1024> str; ... str += str_var1 + str_var2;',data:[309,298,310,297,365,829]}
]}</script>
<div class="benchset" id="bs24"><h4><a id="bs130432147582115154460" href="#bs130432147582115154460">#</a>&nbsp;Append text, number, text</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1283">std::stringstream str; str &lt;&lt; &quot;test = &quot; &lt;&lt; k &lt;&lt; &quot; times&quot;;</a><span class="tooltiptext code">void AppendStreamStrNumStr(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned k = 1; k &lt;= 1&#39;000&#39;000&#39;000; k *= 10) {
std::stringstream t;
t &lt;&lt; &quot;test = &quot; &lt;&lt; k &lt;&lt; &quot; times&quot;;
std::string result = t.str();
#ifdef CHECK_RESULT
if (!result.starts_with(&quot;test = &quot;) || !result.ends_with(&quot; times&quot;)) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
}</span></span></td><td></td><td class="benchmarkresult">3067</td><td class="benchmarkresult">3419</td><td class="benchmarkresult">3033</td><td class="benchmarkresult">10833</td><td class="benchmarkresult">11725</td><td class="benchmarkresult">11412</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1301">std::string str = &quot;test = &quot; + std::to_string(k) + &quot; times&quot;;</a><span class="tooltiptext code">void AppendStdStringStrNumStr(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned k = 1; k &lt;= 1&#39;000&#39;000&#39;000; k *= 10) {
std::string result = &quot;test = &quot; + std::to_string(k) + &quot; times&quot;;
#ifdef CHECK_RESULT
if (!result.starts_with(&quot;test = &quot;) || !result.ends_with(&quot; times&quot;)) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
}</span></span></td><td></td><td class="benchmarkresult">457</td><td class="benchmarkresult">474</td><td class="benchmarkresult">427</td><td class="benchmarkresult">1053</td><td class="benchmarkresult">1226</td><td class="benchmarkresult">1772</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1317">char buf[100]; sprintf(buf, &quot;test = %u times&quot;, k); std::string str = buf;</a><span class="tooltiptext code">void AppendSprintfStrNumStr(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned k = 1; k &lt;= 1&#39;000&#39;000&#39;000; k *= 10) {
char buf[100];
std::sprintf(buf, &quot;test = %u times&quot;, k);
std::string result = buf;
#ifdef CHECK_RESULT
if (!result.starts_with(&quot;test = &quot;) || !result.ends_with(&quot; times&quot;)) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
}</span></span></td><td></td><td class="benchmarkresult">1393</td><td class="benchmarkresult">1229</td><td class="benchmarkresult">1487</td><td class="benchmarkresult">2810</td><td class="benchmarkresult">2815</td><td class="benchmarkresult">5285</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1335">std::string str = std::format(&quot;test = {} times&quot;, k);</a><span class="tooltiptext code">void AppendFormatStrNumStr(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned k = 1; k &lt;= 1&#39;000&#39;000&#39;000; k *= 10) {
std::string result = std::format(&quot;test = {} times&quot;, k);
#ifdef CHECK_RESULT
if (!result.starts_with(&quot;test = &quot;) || !result.ends_with(&quot; times&quot;)) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
}</span></span></td><td></td><td class="benchmarkresult">1140</td><td class="benchmarkresult">959</td><td class="benchmarkresult">1206</td><td class="benchmarkresult">1904</td><td class="benchmarkresult">2391</td><td class="benchmarkresult">2834</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1351">lstringa&lt;8> str; str.format(&quot;test = {} times&quot;, k);</a><span class="tooltiptext code">template&lt;typename T>
void AppendSimStrStrNumStrF(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned k = 1; k &lt;= 1&#39;000&#39;000&#39;000; k *= 10) {
T result;
result.format(&quot;test = {} times&quot;, k);
#ifdef CHECK_RESULT
if (!result.starts_with(&quot;test = &quot;) || !result.ends_with(&quot; times&quot;)) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">В simstr format с первого раза не помещается в такую строку без аллокации.
In simstr format, the first time it doesn't fit into such a
string without allocation.</span></span></td><td class="benchmarkresult">1356</td><td class="benchmarkresult">2002</td><td class="benchmarkresult">1559</td><td class="benchmarkresult">2003</td><td class="benchmarkresult">2677</td><td class="benchmarkresult">4681</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1351">lstringa&lt;32> str; str.format(&quot;test = {} times&quot;, k);</a><span class="tooltiptext code">template&lt;typename T>
void AppendSimStrStrNumStrF(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned k = 1; k &lt;= 1&#39;000&#39;000&#39;000; k *= 10) {
T result;
result.format(&quot;test = {} times&quot;, k);
#ifdef CHECK_RESULT
if (!result.starts_with(&quot;test = &quot;) || !result.ends_with(&quot; times&quot;)) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">А в такую помещается. Используйте сразу буфера подходящего размера.
And it fits in this one. Use buffers of the appropriate size right away.</span></span></td><td class="benchmarkresult">1002</td><td class="benchmarkresult">1745</td><td class="benchmarkresult">1054</td><td class="benchmarkresult">962</td><td class="benchmarkresult">1480</td><td class="benchmarkresult">4054</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1369">lstringa&lt;8> str = &quot;test = &quot; + k + &quot; times&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void AppendSimStrStrNumStr(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned k = 1; k &lt;= 1&#39;000&#39;000&#39;000; k *= 10) {
T result = &quot;test = &quot;_ss + k + &quot; times&quot;;
#ifdef CHECK_RESULT
if (!result.starts_with(&quot;test = &quot;) || !result.ends_with(&quot; times&quot;)) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Результат не помещается в SSO, возникает аллокация.
The result does not fit into SSO, an allocation occurs.</span></span></td><td class="benchmarkresult">262</td><td class="benchmarkresult">263</td><td class="benchmarkresult">290</td><td class="benchmarkresult">807</td><td class="benchmarkresult">890</td><td class="benchmarkresult">555</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1369">lstringa&lt;32> str = &quot;test = &quot; + k + &quot; times&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void AppendSimStrStrNumStr(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned k = 1; k &lt;= 1&#39;000&#39;000&#39;000; k *= 10) {
T result = &quot;test = &quot;_ss + k + &quot; times&quot;;
#ifdef CHECK_RESULT
if (!result.starts_with(&quot;test = &quot;) || !result.ends_with(&quot; times&quot;)) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">А здесь и ниже - результат укладывается в SSO.
Ещё раз - используйте сразу буфера подходящего размера.
And here and below, the result fits within SSO.
Once again, use appropriately sized buffers from the start.</span></span></td><td class="benchmarkresult">126</td><td class="benchmarkresult">119</td><td class="benchmarkresult">136</td><td class="benchmarkresult">134</td><td class="benchmarkresult">180</td><td class="benchmarkresult">339</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1369">stringa str = &quot;test = &quot; + k + &quot; times&quot;;</a><span class="tooltiptext code">template&lt;typename T>
void AppendSimStrStrNumStr(benchmark::State&amp; state) {
for (auto _: state) {
for (unsigned k = 1; k &lt;= 1&#39;000&#39;000&#39;000; k *= 10) {
T result = &quot;test = &quot;_ss + k + &quot; times&quot;;
#ifdef CHECK_RESULT
if (!result.starts_with(&quot;test = &quot;) || !result.ends_with(&quot; times&quot;)) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Под WASM размер SSO 15 символов, что явно не хватает для размещения
результата, отсюда и такое время.
Under WASM, the SSO size is 15 characters, which is clearly not
enough to accommodate the result, hence the long time.</span></span></td><td class="benchmarkresult">124</td><td class="benchmarkresult">118</td><td class="benchmarkresult">137</td><td class="benchmarkresult">126</td><td class="benchmarkresult">172</td><td class="benchmarkresult">511</td></tr>
</tbody></table></div><script>bench_sets['Append text, number, text'] = {id:'bs24', tests:[
{name:'std::stringstream str; str << "test = " << k << " times";',data:[3067,3419,3033,10833,11725,11412]},
{name:'std::string str = "test = " + std::to_string(k) + " times";',data:[457,474,427,1053,1226,1772]},
{name:'char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;',data:[1393,1229,1487,2810,2815,5285]},
{name:'std::string str = std::format("test = {} times", k);',data:[1140,959,1206,1904,2391,2834]},
{name:'lstringa<8> str; str.format("test = {} times", k);',data:[1356,2002,1559,2003,2677,4681]},
{name:'lstringa<32> str; str.format("test = {} times", k);',data:[1002,1745,1054,962,1480,4054]},
{name:'lstringa<8> str = "test = " + k + " times";',data:[262,263,290,807,890,555]},
{name:'lstringa<32> str = "test = " + k + " times";',data:[126,119,136,134,180,339]},
{name:'stringa str = "test = " + k + " times";',data:[124,118,137,126,172,511]}
]}</script>
<div class="benchset" id="bs25"><h4><a id="bs7106975351756760120" href="#bs7106975351756760120">#</a>&nbsp;Split text and convert to int</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1399">std::string::find + substr + std::strtol</a><span class="tooltiptext code">void SplitConvertIntStdString(benchmark::State&amp; state) {
std::string numbers = NUMBER_LIST;
for (auto _: state) {
int total = 0;
for (size_t start = 0; start &lt; numbers.length(); ) {
int delim = numbers.find(&quot;-!-&quot;, 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(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(total);
benchmark::DoNotOptimize(numbers);
}
}</span></span></td><td></td><td class="benchmarkresult">270</td><td class="benchmarkresult">277</td><td class="benchmarkresult">275</td><td class="benchmarkresult">558</td><td class="benchmarkresult">573</td><td class="benchmarkresult">660</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1423">ssa::splitter + ssa::as_int</a><span class="tooltiptext code">void SplitConvertIntSimStr(benchmark::State&amp; state) {
stra numbers = NUMBER_LIST;
for (auto _: state) {
int total = 0;
for (auto splitter = numbers.splitter(&quot;-!-&quot;); !splitter.is_done();) {
total += splitter.next().as_int&lt;int>();
}
#ifdef CHECK_RESULT
if (total != 218) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(total);
benchmark::DoNotOptimize(numbers);
}
}</span></span></td><td></td><td class="benchmarkresult">156</td><td class="benchmarkresult">159</td><td class="benchmarkresult">192</td><td class="benchmarkresult">176</td><td class="benchmarkresult">304</td><td class="benchmarkresult">245</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1440">ssa::splitf + functor</a><span class="tooltiptext code">void SplitConvertIntSplitf(benchmark::State&amp; state) {
stra numbers = NUMBER_LIST;
for (auto _: state) {
int total = 0;
numbers.splitf&lt;void>(&quot;-!-&quot;, [&amp;](ssa&amp; part){total += part.as_int&lt;int>();});
#ifdef CHECK_RESULT
if (total != 218) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(total);
benchmark::DoNotOptimize(numbers);
}
}</span></span></td><td></td><td class="benchmarkresult">207</td><td class="benchmarkresult">213</td><td class="benchmarkresult">196</td><td class="benchmarkresult">192</td><td class="benchmarkresult">218</td><td class="benchmarkresult">271</td></tr>
</tbody></table></div><script>bench_sets['Split text and convert to int'] = {id:'bs25', tests:[
{name:'std::string::find + substr + std::strtol',data:[270,277,275,558,573,660]},
{name:'ssa::splitter + ssa::as_int',data:[156,159,192,176,304,245]},
{name:'ssa::splitf + functor',data:[207,213,196,192,218,271]}
]}</script>
<div class="benchset" id="bs26"><h4><a id="bs151373809886162287550" href="#bs151373809886162287550">#</a>&nbsp;Replace symbols in text ~400 symbols</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1461">Naive (and wrong) replace symbols with std::string find + replace</a><span class="tooltiptext code">void ReplaceSymbolsStdStringNaiveWrong(benchmark::State&amp; state) {
std::string_view source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
;
std::vector&lt;std::pair&lt;u8s, std::string_view>> repl = {
{&#39;&amp;&#39;, &quot;&amp;amp;&quot;},
{&#39;-&#39;, &quot;&quot;},
{&#39;&lt;&#39;, &quot;&amp;lt;&quot;},
{&#39;>&#39;, &quot;&amp;gt;&quot;},
{&#39;\&#39;&#39;, &quot;&amp;#39;&quot;},
{&#39;\&quot;&#39;, &quot;&amp;quot;&quot;}
};
auto repl_all = [](std::string&amp; 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&amp; r : repl) {
repl_all(result, r.first, r.second);
}
#ifdef CHECK_RESULT
if (result
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Это наивная реализация, которая неверно отработает на
таких заменах, как 'a'->'b' и 'b'->'a'. Но если замены не конфликтуют,
то работает быстро.
This is a naive implementation that will fail to handle substitutions
such as 'a'->'b' and 'b'->'a'. But if the substitutions don't conflict,
it works quickly.</span></span></td><td class="benchmarkresult">844</td><td class="benchmarkresult">916</td><td class="benchmarkresult">822</td><td class="benchmarkresult">1124</td><td class="benchmarkresult">1206</td><td class="benchmarkresult">2872</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1515">replace symbols with std::string find_first_of + replace</a><span class="tooltiptext code">void ReplaceSymbolsStdStringNaiveRight(benchmark::State&amp; state) {
std::string_view source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
;
std::vector&lt;std::pair&lt;u8s, std::string_view>> repl = {
{&#39;-&#39;, &quot;&quot;},
{&#39;&lt;&#39;, &quot;&amp;lt;&quot;},
{&#39;>&#39;, &quot;&amp;gt;&quot;},
{&#39;\&#39;&#39;, &quot;&amp;#39;&quot;},
{&#39;\&quot;&#39;, &quot;&amp;quot;&quot;},
{&#39;&amp;&#39;, &quot;&amp;amp;&quot;},
};
for (auto _: state) {
std::string result{source};
std::string pattern;
for (const auto&amp; 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
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Дальше уже правильные реализации, не зависящие от конфликтующих замен.
Further, there are correct implementations that do not depend on
conflicting replacements.</span></span></td><td class="benchmarkresult">2647</td><td class="benchmarkresult">2428</td><td class="benchmarkresult">2428</td><td class="benchmarkresult">1940</td><td class="benchmarkresult">2200</td><td class="benchmarkresult">5223</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1569">replace symbols with std::string_view find_first_of + copy</a><span class="tooltiptext code">void ReplaceSymbolsStdString(benchmark::State&amp; state) {
std::string_view source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
;
const std::string_view repl_from = &quot;-&lt;>&#39;\&quot;&amp;&quot;;
const std::string_view repl_to[] = {&quot;&quot;, &quot;&amp;lt;&quot;, &quot;&amp;gt;&quot;, &quot;&amp;#39;&quot;, &quot;&amp;quot;&quot;, &quot;&amp;amp;&quot;};
for (auto _: state) {
std::string result;
for (size_t start = 0; start &lt; 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
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">1123</td><td class="benchmarkresult">1026</td><td class="benchmarkresult">1065</td><td class="benchmarkresult">2359</td><td class="benchmarkresult">2544</td><td class="benchmarkresult">2704</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1622">replace runtime symbols with string expressions and without remembering all search results</a><span class="tooltiptext code">template&lt;bool UseVector>
void ReplaceSymbolsDynPatternSimStr(benchmark::State&amp; state) {
stra source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
;
std::vector&lt;std::pair&lt;u8s, ssa>> repl = {
{&#39;-&#39;, &quot;&quot;},
{&#39;&lt;&#39;, &quot;&amp;lt;&quot;},
{&#39;>&#39;, &quot;&amp;gt;&quot;},
{&#39;\&#39;&#39;, &quot;&amp;#39;&quot;},
{&#39;\&quot;&#39;, &quot;&amp;quot;&quot;},
{&#39;&amp;&#39;, &quot;&amp;amp;&quot;},
};
for (auto _: state) {
stringa result = expr_replace_symbols&lt;u8s, UseVector>{source, repl};
#ifdef CHECK_RESULT
if (result
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">1273</td><td class="benchmarkresult">1408</td><td class="benchmarkresult">1372</td><td class="benchmarkresult">1654</td><td class="benchmarkresult">1663</td><td class="benchmarkresult">2675</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1622">replace runtime symbols with simstr and memorization of all search results</a><span class="tooltiptext code">template&lt;bool UseVector>
void ReplaceSymbolsDynPatternSimStr(benchmark::State&amp; state) {
stra source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
;
std::vector&lt;std::pair&lt;u8s, ssa>> repl = {
{&#39;-&#39;, &quot;&quot;},
{&#39;&lt;&#39;, &quot;&amp;lt;&quot;},
{&#39;>&#39;, &quot;&amp;gt;&quot;},
{&#39;\&#39;&#39;, &quot;&amp;#39;&quot;},
{&#39;\&quot;&#39;, &quot;&amp;quot;&quot;},
{&#39;&amp;&#39;, &quot;&amp;amp;&quot;},
};
for (auto _: state) {
stringa result = expr_replace_symbols&lt;u8s, UseVector>{source, repl};
#ifdef CHECK_RESULT
if (result
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">1067</td><td class="benchmarkresult">1083</td><td class="benchmarkresult">1016</td><td class="benchmarkresult">1483</td><td class="benchmarkresult">1442</td><td class="benchmarkresult">2107</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1669">replace const symbols with string expressions and without remembering all search results</a><span class="tooltiptext code">template&lt;bool UseVector>
void ReplaceSymbolsCons2PatternSimStr(benchmark::State&amp; state) {
stra source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
;
for (auto _: state) {
stringa result = e_repl_const_symbols&lt;UseVector>(source,
&#39;-&#39;, &quot;&quot;,
&#39;&lt;&#39;, &quot;&amp;lt;&quot;,
&#39;>&#39;, &quot;&amp;gt;&quot;,
&#39;\&#39;&#39;, &quot;&amp;#39;&quot;,
&#39;\&quot;&#39;, &quot;&amp;quot;&quot;,
&#39;&amp;&#39;, &quot;&amp;amp;&quot;
);
#ifdef CHECK_RESULT
if (result
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">1029</td><td class="benchmarkresult">1128</td><td class="benchmarkresult">1045</td><td class="benchmarkresult">1122</td><td class="benchmarkresult">1293</td><td class="benchmarkresult">2227</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1669">replace const symbols with string expressions and memorization of all search results</a><span class="tooltiptext code">template&lt;bool UseVector>
void ReplaceSymbolsCons2PatternSimStr(benchmark::State&amp; state) {
stra source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
&quot; ksjd-fksjd \&quot;dkjfs-jkhdf dfj &#39; kdkd \&quot;dkfdkfkdjf&quot;
;
for (auto _: state) {
stringa result = e_repl_const_symbols&lt;UseVector>(source,
&#39;-&#39;, &quot;&quot;,
&#39;&lt;&#39;, &quot;&amp;lt;&quot;,
&#39;>&#39;, &quot;&amp;gt;&quot;,
&#39;\&#39;&#39;, &quot;&amp;#39;&quot;,
&#39;\&quot;&#39;, &quot;&amp;quot;&quot;,
&#39;&amp;&#39;, &quot;&amp;amp;&quot;
);
#ifdef CHECK_RESULT
if (result
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
&quot; ksjdfksjd &amp;quot;dkjfsjkhdf dfj &amp;#39; kdkd &amp;quot;dkfdkfkdjf&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">887</td><td class="benchmarkresult">820</td><td class="benchmarkresult">837</td><td class="benchmarkresult">1170</td><td class="benchmarkresult">1213</td><td class="benchmarkresult">1872</td></tr>
</tbody></table></div><script>bench_sets['Replace symbols in text ~400 symbols'] = {id:'bs26', tests:[
{name:'Naive (and wrong) replace symbols with std::string find + replace',data:[844,916,822,1124,1206,2872]},
{name:'replace symbols with std::string find_first_of + replace',data:[2647,2428,2428,1940,2200,5223]},
{name:'replace symbols with std::string_view find_first_of + copy',data:[1123,1026,1065,2359,2544,2704]},
{name:'replace runtime symbols with string expressions and without remembering all search results',data:[1273,1408,1372,1654,1663,2675]},
{name:'replace runtime symbols with simstr and memorization of all search results',data:[1067,1083,1016,1483,1442,2107]},
{name:'replace const symbols with string expressions and without remembering all search results',data:[1029,1128,1045,1122,1293,2227]},
{name:'replace const symbols with string expressions and memorization of all search results',data:[887,820,837,1170,1213,1872]}
]}</script>
<div class="benchset" id="bs27"><h4><a id="bs96756339547767401190" href="#bs96756339547767401190">#</a>&nbsp;Replace symbols in text ~40 symbols</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1723">Short Naive (and wrong) replace symbols with std::string find + replace</a><span class="tooltiptext code">void ShortReplaceSymbolsStdStringNaiveWrong(benchmark::State&amp; state) {
std::string_view source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
;
std::vector&lt;std::pair&lt;u8s, std::string_view>> repl = {
{&#39;&amp;&#39;, &quot;&amp;amp;&quot;},
{&#39;-&#39;, &quot;&quot;},
{&#39;&lt;&#39;, &quot;&amp;lt;&quot;},
{&#39;>&#39;, &quot;&amp;gt;&quot;},
{&#39;\&#39;&#39;, &quot;&amp;#39;&quot;},
{&#39;\&quot;&#39;, &quot;&amp;quot;&quot;}
};
auto repl_all = [](std::string&amp; 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&amp; r : repl) {
repl_all(result, r.first, r.second);
}
#ifdef CHECK_RESULT
if (result
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">166</td><td class="benchmarkresult">177</td><td class="benchmarkresult">161</td><td class="benchmarkresult">308</td><td class="benchmarkresult">328</td><td class="benchmarkresult">472</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1763">Short replace symbols with std::string find_first_of + replace</a><span class="tooltiptext code">void ShortReplaceSymbolsStdStringNaiveRight(benchmark::State&amp; state) {
std::string_view source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
;
std::vector&lt;std::pair&lt;u8s, std::string_view>> repl = {
{&#39;-&#39;, &quot;&quot;},
{&#39;&lt;&#39;, &quot;&amp;lt;&quot;},
{&#39;>&#39;, &quot;&amp;gt;&quot;},
{&#39;\&#39;&#39;, &quot;&amp;#39;&quot;},
{&#39;\&quot;&#39;, &quot;&amp;quot;&quot;},
{&#39;&amp;&#39;, &quot;&amp;amp;&quot;},
};
for (auto _: state) {
std::string result{source};
std::string pattern;
for (const auto&amp; 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
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">334</td><td class="benchmarkresult">324</td><td class="benchmarkresult">329</td><td class="benchmarkresult">364</td><td class="benchmarkresult">420</td><td class="benchmarkresult">718</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1803">Short replace symbols with std::string_view find_first_of + copy</a><span class="tooltiptext code">void ShortReplaceSymbolsStdString(benchmark::State&amp; state) {
std::string_view source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
;
const std::string_view repl_from = &quot;-&lt;>&#39;\&quot;&amp;&quot;;
const std::string_view repl_to[] = {&quot;&quot;, &quot;&amp;lt;&quot;, &quot;&amp;gt;&quot;, &quot;&amp;#39;&quot;, &quot;&amp;quot;&quot;, &quot;&amp;amp;&quot;};
for (auto _: state) {
std::string result;
for (size_t start = 0; start &lt; 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
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">154</td><td class="benchmarkresult">141</td><td class="benchmarkresult">154</td><td class="benchmarkresult">305</td><td class="benchmarkresult">333</td><td class="benchmarkresult">433</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1842">Short replace runtime symbols with string expressions and without remembering all search results</a><span class="tooltiptext code">template&lt;bool UseVector>
void ShortReplaceSymbolsDynPatternSimStr(benchmark::State&amp; state) {
stra source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
;
std::vector&lt;std::pair&lt;u8s, ssa>> repl = {
{&#39;-&#39;, &quot;&quot;},
{&#39;&lt;&#39;, &quot;&amp;lt;&quot;},
{&#39;>&#39;, &quot;&amp;gt;&quot;},
{&#39;\&#39;&#39;, &quot;&amp;#39;&quot;},
{&#39;\&quot;&#39;, &quot;&amp;quot;&quot;},
{&#39;&amp;&#39;, &quot;&amp;amp;&quot;},
};
for (auto _: state) {
stringa result = expr_replace_symbols&lt;u8s, UseVector>{source, repl};
#ifdef CHECK_RESULT
if (result
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">169</td><td class="benchmarkresult">198</td><td class="benchmarkresult">180</td><td class="benchmarkresult">269</td><td class="benchmarkresult">310</td><td class="benchmarkresult">378</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1842">Short replace runtime symbols with simstr and memorization of all search results</a><span class="tooltiptext code">template&lt;bool UseVector>
void ShortReplaceSymbolsDynPatternSimStr(benchmark::State&amp; state) {
stra source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
;
std::vector&lt;std::pair&lt;u8s, ssa>> repl = {
{&#39;-&#39;, &quot;&quot;},
{&#39;&lt;&#39;, &quot;&amp;lt;&quot;},
{&#39;>&#39;, &quot;&amp;gt;&quot;},
{&#39;\&#39;&#39;, &quot;&amp;#39;&quot;},
{&#39;\&quot;&#39;, &quot;&amp;quot;&quot;},
{&#39;&amp;&#39;, &quot;&amp;amp;&quot;},
};
for (auto _: state) {
stringa result = expr_replace_symbols&lt;u8s, UseVector>{source, repl};
#ifdef CHECK_RESULT
if (result
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">201</td><td class="benchmarkresult">186</td><td class="benchmarkresult">184</td><td class="benchmarkresult">366</td><td class="benchmarkresult">401</td><td class="benchmarkresult">391</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1875">Short replace const symbols with string expressions and without remembering all search results</a><span class="tooltiptext code">template&lt;bool UseVector>
void ShortReplaceSymbolsCons2PatternSimStr(benchmark::State&amp; state) {
stra source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
;
for (auto _: state) {
stringa result = e_repl_const_symbols&lt;UseVector>(source,
&#39;-&#39;, &quot;&quot;,
&#39;&lt;&#39;, &quot;&amp;lt;&quot;,
&#39;>&#39;, &quot;&amp;gt;&quot;,
&#39;\&#39;&#39;, &quot;&amp;#39;&quot;,
&#39;\&quot;&#39;, &quot;&amp;quot;&quot;,
&#39;&amp;&#39;, &quot;&amp;amp;&quot;
);
#ifdef CHECK_RESULT
if (result
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">130</td><td class="benchmarkresult">126</td><td class="benchmarkresult">139</td><td class="benchmarkresult">202</td><td class="benchmarkresult">254</td><td class="benchmarkresult">271</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1875">Short replace const symbols with string expressions and memorization of all search results</a><span class="tooltiptext code">template&lt;bool UseVector>
void ShortReplaceSymbolsCons2PatternSimStr(benchmark::State&amp; state) {
stra source =
&quot;abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj >&quot;
;
for (auto _: state) {
stringa result = e_repl_const_symbols&lt;UseVector>(source,
&#39;-&#39;, &quot;&quot;,
&#39;&lt;&#39;, &quot;&amp;lt;&quot;,
&#39;>&#39;, &quot;&amp;gt;&quot;,
&#39;\&#39;&#39;, &quot;&amp;#39;&quot;,
&#39;\&quot;&#39;, &quot;&amp;quot;&quot;,
&#39;&amp;&#39;, &quot;&amp;amp;&quot;
);
#ifdef CHECK_RESULT
if (result
!=
&quot;abcdefg124 &amp;lt; jhsfjsh sjdfsh jfhjd &amp;amp;&amp;amp; jdjdj &amp;gt;&quot;
) {
state.SkipWithError(&quot;not equal&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">145</td><td class="benchmarkresult">136</td><td class="benchmarkresult">132</td><td class="benchmarkresult">293</td><td class="benchmarkresult">334</td><td class="benchmarkresult">294</td></tr>
</tbody></table></div><script>bench_sets['Replace symbols in text ~40 symbols'] = {id:'bs27', tests:[
{name:'Short Naive (and wrong) replace symbols with std::string find + replace',data:[166,177,161,308,328,472]},
{name:'Short replace symbols with std::string find_first_of + replace',data:[334,324,329,364,420,718]},
{name:'Short replace symbols with std::string_view find_first_of + copy',data:[154,141,154,305,333,433]},
{name:'Short replace runtime symbols with string expressions and without remembering all search results',data:[169,198,180,269,310,378]},
{name:'Short replace runtime symbols with simstr and memorization of all search results',data:[201,186,184,366,401,391]},
{name:'Short replace const symbols with string expressions and without remembering all search results',data:[130,126,139,202,254,271]},
{name:'Short replace const symbols with string expressions and memorization of all search results',data:[145,136,132,293,334,294]}
]}</script>
<div class="benchset" id="bs28"><h4><a id="bs77745698784557935900" href="#bs77745698784557935900">#</a>&nbsp;Replace All Str To Longer Size</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1914">replace bb to ---- in std::string|64</a><span class="tooltiptext code">template&lt;size_t Long>
void ReplaceAllLongerStdString(benchmark::State&amp; state) {
std::string_view source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
std::string_view sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
std::string_view pattern = &quot;bb&quot;;
std::string_view repl = &quot;----&quot;;
std::string big_source, big_sample;
for (int i = 0; i &lt; 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(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">151</td><td class="benchmarkresult">180</td><td class="benchmarkresult">154</td><td class="benchmarkresult">223</td><td class="benchmarkresult">242</td><td class="benchmarkresult">363</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1914">replace bb to ---- in std::string|256</a><span class="tooltiptext code">template&lt;size_t Long>
void ReplaceAllLongerStdString(benchmark::State&amp; state) {
std::string_view source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
std::string_view sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
std::string_view pattern = &quot;bb&quot;;
std::string_view repl = &quot;----&quot;;
std::string big_source, big_sample;
for (int i = 0; i &lt; 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(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">603</td><td class="benchmarkresult">842</td><td class="benchmarkresult">504</td><td class="benchmarkresult">727</td><td class="benchmarkresult">791</td><td class="benchmarkresult">1189</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1914">replace bb to ---- in std::string|512</a><span class="tooltiptext code">template&lt;size_t Long>
void ReplaceAllLongerStdString(benchmark::State&amp; state) {
std::string_view source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
std::string_view sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
std::string_view pattern = &quot;bb&quot;;
std::string_view repl = &quot;----&quot;;
std::string big_source, big_sample;
for (int i = 0; i &lt; 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(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">1060</td><td class="benchmarkresult">1259</td><td class="benchmarkresult">1000</td><td class="benchmarkresult">1418</td><td class="benchmarkresult">1464</td><td class="benchmarkresult">2210</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1914">replace bb to ---- in std::string|1024</a><span class="tooltiptext code">template&lt;size_t Long>
void ReplaceAllLongerStdString(benchmark::State&amp; state) {
std::string_view source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
std::string_view sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
std::string_view pattern = &quot;bb&quot;;
std::string_view repl = &quot;----&quot;;
std::string big_source, big_sample;
for (int i = 0; i &lt; 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(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">2332</td><td class="benchmarkresult">2422</td><td class="benchmarkresult">2347</td><td class="benchmarkresult">3058</td><td class="benchmarkresult">3204</td><td class="benchmarkresult">4756</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1914">replace bb to ---- in std::string|2048</a><span class="tooltiptext code">template&lt;size_t Long>
void ReplaceAllLongerStdString(benchmark::State&amp; state) {
std::string_view source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
std::string_view sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
std::string_view pattern = &quot;bb&quot;;
std::string_view repl = &quot;----&quot;;
std::string big_source, big_sample;
for (int i = 0; i &lt; 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(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">5851</td><td class="benchmarkresult">6347</td><td class="benchmarkresult">5969</td><td class="benchmarkresult">8038</td><td class="benchmarkresult">8080</td><td class="benchmarkresult">11109</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1948">replace bb to ---- in lstringa&lt;8>|64</a><span class="tooltiptext code">template&lt;size_t N, size_t Count>
void ReplaceAllLongerSimString(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
lstringa&lt;N> result = big_source;
result.replace(&quot;bb&quot;, &quot;----&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">127</td><td class="benchmarkresult">129</td><td class="benchmarkresult">138</td><td class="benchmarkresult">216</td><td class="benchmarkresult">225</td><td class="benchmarkresult">292</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1948">replace bb to ---- in lstringa&lt;8>|256</a><span class="tooltiptext code">template&lt;size_t N, size_t Count>
void ReplaceAllLongerSimString(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
lstringa&lt;N> result = big_source;
result.replace(&quot;bb&quot;, &quot;----&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">442</td><td class="benchmarkresult">444</td><td class="benchmarkresult">444</td><td class="benchmarkresult">606</td><td class="benchmarkresult">655</td><td class="benchmarkresult">913</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1948">replace bb to ---- in lstringa&lt;8>|512</a><span class="tooltiptext code">template&lt;size_t N, size_t Count>
void ReplaceAllLongerSimString(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
lstringa&lt;N> result = big_source;
result.replace(&quot;bb&quot;, &quot;----&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">831</td><td class="benchmarkresult">828</td><td class="benchmarkresult">899</td><td class="benchmarkresult">1002</td><td class="benchmarkresult">1124</td><td class="benchmarkresult">1685</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1948">replace bb to ---- in lstringa&lt;8>|1024</a><span class="tooltiptext code">template&lt;size_t N, size_t Count>
void ReplaceAllLongerSimString(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
lstringa&lt;N> result = big_source;
result.replace(&quot;bb&quot;, &quot;----&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">1698</td><td class="benchmarkresult">1614</td><td class="benchmarkresult">1751</td><td class="benchmarkresult">1848</td><td class="benchmarkresult">2038</td><td class="benchmarkresult">3100</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1948">replace bb to ---- in lstringa&lt;8>|2048</a><span class="tooltiptext code">template&lt;size_t N, size_t Count>
void ReplaceAllLongerSimString(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
lstringa&lt;N> result = big_source;
result.replace(&quot;bb&quot;, &quot;----&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">3256</td><td class="benchmarkresult">3127</td><td class="benchmarkresult">3301</td><td class="benchmarkresult">3556</td><td class="benchmarkresult">3964</td><td class="benchmarkresult">6119</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1971">replace bb to ---- by init stringa|64</a><span class="tooltiptext code">template&lt;size_t Count>
void ReplaceAllLongerSimStringExpr(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source, &quot;bb&quot;, &quot;----&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">91.5</td><td class="benchmarkresult">90.9</td><td class="benchmarkresult">92.8</td><td class="benchmarkresult">165</td><td class="benchmarkresult">196</td><td class="benchmarkresult">187</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1971">replace bb to ---- by init stringa|256</a><span class="tooltiptext code">template&lt;size_t Count>
void ReplaceAllLongerSimStringExpr(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source, &quot;bb&quot;, &quot;----&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">306</td><td class="benchmarkresult">308</td><td class="benchmarkresult">287</td><td class="benchmarkresult">366</td><td class="benchmarkresult">456</td><td class="benchmarkresult">580</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1971">replace bb to ---- by init stringa|512</a><span class="tooltiptext code">template&lt;size_t Count>
void ReplaceAllLongerSimStringExpr(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source, &quot;bb&quot;, &quot;----&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">718</td><td class="benchmarkresult">709</td><td class="benchmarkresult">705</td><td class="benchmarkresult">793</td><td class="benchmarkresult">1064</td><td class="benchmarkresult">1341</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1971">replace bb to ---- by init stringa|1024</a><span class="tooltiptext code">template&lt;size_t Count>
void ReplaceAllLongerSimStringExpr(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source, &quot;bb&quot;, &quot;----&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">1629</td><td class="benchmarkresult">1392</td><td class="benchmarkresult">1550</td><td class="benchmarkresult">1626</td><td class="benchmarkresult">2161</td><td class="benchmarkresult">2813</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1971">replace bb to ---- by init stringa|2048</a><span class="tooltiptext code">template&lt;size_t Count>
void ReplaceAllLongerSimStringExpr(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source, &quot;bb&quot;, &quot;----&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">3400</td><td class="benchmarkresult">2810</td><td class="benchmarkresult">3106</td><td class="benchmarkresult">3047</td><td class="benchmarkresult">4481</td><td class="benchmarkresult">5550</td></tr>
</tbody></table></div><script>bench_sets['Replace All Str To Longer Size'] = {id:'bs28', tests:[
{name:'replace bb to ---- in std::string|64',data:[151,180,154,223,242,363]},
{name:'replace bb to ---- in std::string|256',data:[603,842,504,727,791,1189]},
{name:'replace bb to ---- in std::string|512',data:[1060,1259,1000,1418,1464,2210]},
{name:'replace bb to ---- in std::string|1024',data:[2332,2422,2347,3058,3204,4756]},
{name:'replace bb to ---- in std::string|2048',data:[5851,6347,5969,8038,8080,11109]},
{name:'replace bb to ---- in lstringa<8>|64',data:[127,129,138,216,225,292]},
{name:'replace bb to ---- in lstringa<8>|256',data:[442,444,444,606,655,913]},
{name:'replace bb to ---- in lstringa<8>|512',data:[831,828,899,1002,1124,1685]},
{name:'replace bb to ---- in lstringa<8>|1024',data:[1698,1614,1751,1848,2038,3100]},
{name:'replace bb to ---- in lstringa<8>|2048',data:[3256,3127,3301,3556,3964,6119]},
{name:'replace bb to ---- by init stringa|64',data:[91.5,90.9,92.8,165,196,187]},
{name:'replace bb to ---- by init stringa|256',data:[306,308,287,366,456,580]},
{name:'replace bb to ---- by init stringa|512',data:[718,709,705,793,1064,1341]},
{name:'replace bb to ---- by init stringa|1024',data:[1629,1392,1550,1626,2161,2813]},
{name:'replace bb to ---- by init stringa|2048',data:[3400,2810,3106,3047,4481,5550]}
]}</script>
<div class="benchset" id="bs29"><h4><a id="bs74494088982050398630" href="#bs74494088982050398630">#</a>&nbsp;Replace All Str To Same Size</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1993">replace bb to -- in std::string|64</a><span class="tooltiptext code">template&lt;size_t Long>
void ReplaceAllEqualStdString(benchmark::State&amp; state) {
std::string_view source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
std::string_view sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
std::string_view pattern = &quot;bb&quot;;
std::string_view repl = &quot;--&quot;;
std::string big_source, big_sample;
for (int i = 0; i &lt; 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(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">114</td><td class="benchmarkresult">130</td><td class="benchmarkresult">131</td><td class="benchmarkresult">187</td><td class="benchmarkresult">198</td><td class="benchmarkresult">243</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1993">replace bb to -- in std::string|256</a><span class="tooltiptext code">template&lt;size_t Long>
void ReplaceAllEqualStdString(benchmark::State&amp; state) {
std::string_view source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
std::string_view sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
std::string_view pattern = &quot;bb&quot;;
std::string_view repl = &quot;--&quot;;
std::string big_source, big_sample;
for (int i = 0; i &lt; 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(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">390</td><td class="benchmarkresult">427</td><td class="benchmarkresult">381</td><td class="benchmarkresult">469</td><td class="benchmarkresult">520</td><td class="benchmarkresult">814</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1993">replace bb to -- in std::string|512</a><span class="tooltiptext code">template&lt;size_t Long>
void ReplaceAllEqualStdString(benchmark::State&amp; state) {
std::string_view source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
std::string_view sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
std::string_view pattern = &quot;bb&quot;;
std::string_view repl = &quot;--&quot;;
std::string big_source, big_sample;
for (int i = 0; i &lt; 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(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">743</td><td class="benchmarkresult">851</td><td class="benchmarkresult">743</td><td class="benchmarkresult">837</td><td class="benchmarkresult">928</td><td class="benchmarkresult">1542</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1993">replace bb to -- in std::string|1024</a><span class="tooltiptext code">template&lt;size_t Long>
void ReplaceAllEqualStdString(benchmark::State&amp; state) {
std::string_view source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
std::string_view sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
std::string_view pattern = &quot;bb&quot;;
std::string_view repl = &quot;--&quot;;
std::string big_source, big_sample;
for (int i = 0; i &lt; 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(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">1477</td><td class="benchmarkresult">1603</td><td class="benchmarkresult">1483</td><td class="benchmarkresult">1612</td><td class="benchmarkresult">1750</td><td class="benchmarkresult">2825</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1993">replace bb to -- in std::string|2048</a><span class="tooltiptext code">template&lt;size_t Long>
void ReplaceAllEqualStdString(benchmark::State&amp; state) {
std::string_view source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
std::string_view sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
std::string_view pattern = &quot;bb&quot;;
std::string_view repl = &quot;--&quot;;
std::string big_source, big_sample;
for (int i = 0; i &lt; 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(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">2929</td><td class="benchmarkresult">3230</td><td class="benchmarkresult">2798</td><td class="benchmarkresult">3131</td><td class="benchmarkresult">3402</td><td class="benchmarkresult">5545</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2026">replace bb to -- in lstringa&lt;8>|64</a><span class="tooltiptext code">template&lt;size_t N, size_t Long>
void ReplaceAllEqualSimString(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
lstringa&lt;2048> big_source{Long, source}, big_sample{Long, sample};
for (auto _: state) {
lstringa&lt;N> result = big_source;
result.replace(&quot;bb&quot;, &quot;--&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">89.2</td><td class="benchmarkresult">90.8</td><td class="benchmarkresult">91.5</td><td class="benchmarkresult">175</td><td class="benchmarkresult">186</td><td class="benchmarkresult">192</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2026">replace bb to -- in lstringa&lt;8>|256</a><span class="tooltiptext code">template&lt;size_t N, size_t Long>
void ReplaceAllEqualSimString(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
lstringa&lt;2048> big_source{Long, source}, big_sample{Long, sample};
for (auto _: state) {
lstringa&lt;N> result = big_source;
result.replace(&quot;bb&quot;, &quot;--&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">295</td><td class="benchmarkresult">294</td><td class="benchmarkresult">302</td><td class="benchmarkresult">427</td><td class="benchmarkresult">442</td><td class="benchmarkresult">636</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2026">replace bb to -- in lstringa&lt;8>|512</a><span class="tooltiptext code">template&lt;size_t N, size_t Long>
void ReplaceAllEqualSimString(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
lstringa&lt;2048> big_source{Long, source}, big_sample{Long, sample};
for (auto _: state) {
lstringa&lt;N> result = big_source;
result.replace(&quot;bb&quot;, &quot;--&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">553</td><td class="benchmarkresult">551</td><td class="benchmarkresult">539</td><td class="benchmarkresult">723</td><td class="benchmarkresult">771</td><td class="benchmarkresult">1150</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2026">replace bb to -- in lstringa&lt;8>|1024</a><span class="tooltiptext code">template&lt;size_t N, size_t Long>
void ReplaceAllEqualSimString(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
lstringa&lt;2048> big_source{Long, source}, big_sample{Long, sample};
for (auto _: state) {
lstringa&lt;N> result = big_source;
result.replace(&quot;bb&quot;, &quot;--&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">1122</td><td class="benchmarkresult">1066</td><td class="benchmarkresult">1121</td><td class="benchmarkresult">1373</td><td class="benchmarkresult">1457</td><td class="benchmarkresult">2296</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2026">replace bb to -- in lstringa&lt;8>|2048</a><span class="tooltiptext code">template&lt;size_t N, size_t Long>
void ReplaceAllEqualSimString(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
lstringa&lt;2048> big_source{Long, source}, big_sample{Long, sample};
for (auto _: state) {
lstringa&lt;N> result = big_source;
result.replace(&quot;bb&quot;, &quot;--&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
}</span></span></td><td></td><td class="benchmarkresult">2088</td><td class="benchmarkresult">2242</td><td class="benchmarkresult">2174</td><td class="benchmarkresult">2685</td><td class="benchmarkresult">2800</td><td class="benchmarkresult">4237</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2048">replace bb to -- by init stringa|64</a><span class="tooltiptext code">template&lt;size_t Count>
void ReplaceAllEqualSimStringExpr(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
ssa pattern = &quot;bb&quot;;
ssa repl = &quot;--&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), &quot;bb&quot;, &quot;--&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">73.9</td><td class="benchmarkresult">83.0</td><td class="benchmarkresult">112</td><td class="benchmarkresult">153</td><td class="benchmarkresult">165</td><td class="benchmarkresult">136</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2048">replace bb to -- by init stringa|256</a><span class="tooltiptext code">template&lt;size_t Count>
void ReplaceAllEqualSimStringExpr(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
ssa pattern = &quot;bb&quot;;
ssa repl = &quot;--&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), &quot;bb&quot;, &quot;--&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">240</td><td class="benchmarkresult">237</td><td class="benchmarkresult">262</td><td class="benchmarkresult">322</td><td class="benchmarkresult">367</td><td class="benchmarkresult">464</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2048">replace bb to -- by init stringa|512</a><span class="tooltiptext code">template&lt;size_t Count>
void ReplaceAllEqualSimStringExpr(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
ssa pattern = &quot;bb&quot;;
ssa repl = &quot;--&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), &quot;bb&quot;, &quot;--&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">434</td><td class="benchmarkresult">435</td><td class="benchmarkresult">479</td><td class="benchmarkresult">520</td><td class="benchmarkresult">632</td><td class="benchmarkresult">838</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2048">replace bb to -- by init stringa|1024</a><span class="tooltiptext code">template&lt;size_t Count>
void ReplaceAllEqualSimStringExpr(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
ssa pattern = &quot;bb&quot;;
ssa repl = &quot;--&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), &quot;bb&quot;, &quot;--&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">898</td><td class="benchmarkresult">851</td><td class="benchmarkresult">954</td><td class="benchmarkresult">954</td><td class="benchmarkresult">1108</td><td class="benchmarkresult">1620</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2048">replace bb to -- by init stringa|2048</a><span class="tooltiptext code">template&lt;size_t Count>
void ReplaceAllEqualSimStringExpr(benchmark::State&amp; state) {
ssa source = &quot;aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba&quot;;
ssa sample = &quot;aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a&quot;;
ssa pattern = &quot;bb&quot;;
ssa repl = &quot;--&quot;;
lstringa&lt;2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), &quot;bb&quot;, &quot;--&quot;);
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout &lt;&lt; result.length() &lt;&lt; &quot;: &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot; &lt;&lt; big_sample.length() &lt;&lt; &quot;: &quot; &lt;&lt; big_sample &lt;&lt; &quot;\n\n&quot;;
state.SkipWithError(&quot;error in replace&quot;);
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
}</span></span></td><td></td><td class="benchmarkresult">1709</td><td class="benchmarkresult">1658</td><td class="benchmarkresult">1809</td><td class="benchmarkresult">1806</td><td class="benchmarkresult">2118</td><td class="benchmarkresult">2774</td></tr>
</tbody></table></div><script>bench_sets['Replace All Str To Same Size'] = {id:'bs29', tests:[
{name:'replace bb to -- in std::string|64',data:[114,130,131,187,198,243]},
{name:'replace bb to -- in std::string|256',data:[390,427,381,469,520,814]},
{name:'replace bb to -- in std::string|512',data:[743,851,743,837,928,1542]},
{name:'replace bb to -- in std::string|1024',data:[1477,1603,1483,1612,1750,2825]},
{name:'replace bb to -- in std::string|2048',data:[2929,3230,2798,3131,3402,5545]},
{name:'replace bb to -- in lstringa<8>|64',data:[89.2,90.8,91.5,175,186,192]},
{name:'replace bb to -- in lstringa<8>|256',data:[295,294,302,427,442,636]},
{name:'replace bb to -- in lstringa<8>|512',data:[553,551,539,723,771,1150]},
{name:'replace bb to -- in lstringa<8>|1024',data:[1122,1066,1121,1373,1457,2296]},
{name:'replace bb to -- in lstringa<8>|2048',data:[2088,2242,2174,2685,2800,4237]},
{name:'replace bb to -- by init stringa|64',data:[73.9,83.0,112,153,165,136]},
{name:'replace bb to -- by init stringa|256',data:[240,237,262,322,367,464]},
{name:'replace bb to -- by init stringa|512',data:[434,435,479,520,632,838]},
{name:'replace bb to -- by init stringa|1024',data:[898,851,954,954,1108,1620]},
{name:'replace bb to -- by init stringa|2048',data:[1709,1658,1809,1806,2118,2774]}
]}</script>
<div class="benchset" id="bs30"><h4><a id="bs8410196985047277720" href="#bs8410196985047277720">#</a>&nbsp;Hash Map insert and find</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2145">hashStrMapA&lt;size_t> emplace &amp; find stringa;</a><span class="tooltiptext code">void HashMapSimStr(benchmark::State&amp; state) {
for (auto _: state) {
hashStrMapA&lt;size_t> store;
for (size_t idx = 0; idx &lt; bs_sim.size(); idx++) {
store.try_emplace(bs_sim[idx], idx);
}
#ifdef CHECK_RESULT
if (store.size() != bs_sim.size()) {
state.SkipWithError(&quot;bad inserts&quot;);
}
#endif
for (size_t idx = 0; idx &lt; bs_sim.size(); idx++) {
auto find = store.find(bs_sim[idx]);
size_t res = find->second;
#ifdef CHECK_RESULT
if (res != idx) {
state.SkipWithError(&quot;bad find&quot;);
}
#endif
benchmark::DoNotOptimize(res);
}
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Вставляем в hashStrMapA 10000 stringa длиной от 30 до 50
символов, а потом ищем их в ней
We insert 10,000 strings of length from 30 to 50 characters into
hashStrMapA, and then search for them in it.</span></span></td><td class="benchmarkresult">3754473</td><td class="benchmarkresult">3780026</td><td class="benchmarkresult">3843202</td><td class="benchmarkresult">4069702</td><td class="benchmarkresult">4479657</td><td class="benchmarkresult">3271665</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2169">std::unordered_map&lt;std::string, size_t> emplace &amp; find std::string;</a><span class="tooltiptext code">void HashMapStdStr(benchmark::State&amp; state) {
for (auto _: state) {
std::unordered_map&lt;std::string, size_t> store;
for (size_t idx = 0; idx &lt; bs_std.size(); idx++) {
store.try_emplace(bs_std[idx], idx);
}
#ifdef CHECK_RESULT
if (store.size() != bs_std.size()) {
state.SkipWithError(&quot;bad inserts&quot;);
}
#endif
for (size_t idx = 0; idx &lt; bs_std.size(); idx++) {
auto find = store.find(bs_std[idx]);
size_t res = find->second;
#ifdef CHECK_RESULT
if (res != idx) {
state.SkipWithError(&quot;bad find&quot;);
}
#endif
benchmark::DoNotOptimize(res);
}
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">То же самое c std::string и std::unordered_map
Same thing with std::string and std::unordered_map</span></span></td><td class="benchmarkresult">3584569</td><td class="benchmarkresult">3706958</td><td class="benchmarkresult">3689411</td><td class="benchmarkresult">5913523</td><td class="benchmarkresult">6065832</td><td class="benchmarkresult">3592775</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2193">hashStrMapA&lt;size_t> emplace &amp; find ssa;</a><span class="tooltiptext code">void HashMapSimSsa(benchmark::State&amp; state) {
for (auto _: state) {
hashStrMapA&lt;size_t> store;
for (size_t idx = 0; idx &lt; bs_sim.size(); idx++) {
store.emplace(bs_sim[idx], idx);
}
#ifdef CHECK_RESULT
if (store.size() != bs_sim.size()) {
state.SkipWithError(&quot;bad inserts&quot;);
}
#endif
for (size_t idx = 0; idx &lt; 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(&quot;bad find&quot;);
}
#endif
benchmark::DoNotOptimize(res);
}
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Теперь вставляем stringa, а ищем ssa
Now we insert stringa and search for ssa</span></span></td><td class="benchmarkresult">3718652</td><td class="benchmarkresult">3815600</td><td class="benchmarkresult">3848145</td><td class="benchmarkresult">3619495</td><td class="benchmarkresult">4127357</td><td class="benchmarkresult">3244867</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2218">std::unordered_map&lt;std::string, size_t> emplace &amp; find std::string_view;</a><span class="tooltiptext code">void HashMapStdStrView(benchmark::State&amp; state) {
for (auto _: state) {
std::unordered_map&lt;std::string, size_t> store;
for (size_t idx = 0; idx &lt; bs_std.size(); idx++) {
store.emplace(bs_std[idx], idx);
}
#ifdef CHECK_RESULT
if (store.size() != bs_std.size()) {
state.SkipWithError(&quot;bad inserts&quot;);
}
#endif
for (size_t idx = 0; idx &lt; 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(&quot;bad find&quot;);
}
#endif
benchmark::DoNotOptimize(res);
}
}
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Вставляем std::string, а ищем std::string_view
We insert std::string and look for std::string_view</span></span></td><td class="benchmarkresult">4196609</td><td class="benchmarkresult">4134155</td><td class="benchmarkresult">4076242</td><td class="benchmarkresult">6497268</td><td class="benchmarkresult">6592167</td><td class="benchmarkresult">4041903</td></tr>
</tbody></table></div><script>bench_sets['Hash Map insert and find'] = {id:'bs30', tests:[
{name:'hashStrMapA<size_t> emplace & find stringa;',data:[3754473,3780026,3843202,4069702,4479657,3271665]},
{name:'std::unordered_map<std::string, size_t> emplace & find std::string;',data:[3584569,3706958,3689411,5913523,6065832,3592775]},
{name:'hashStrMapA<size_t> emplace & find ssa;',data:[3718652,3815600,3848145,3619495,4127357,3244867]},
{name:'std::unordered_map<std::string, size_t> emplace & find std::string_view;',data:[4196609,4134155,4076242,6497268,6592167,4041903]}
]}</script>
<div class="benchset" id="bs31"><h4><a id="bs131384792586914680410" href="#bs131384792586914680410">#</a>&nbsp;Build Full Func Name</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2428">Build func full name std::string;</a><span class="tooltiptext code">std::string build_full_name_std() const {
std::string str{has_ret_type_resolver ? &quot;any&quot;sv : type_names_sv[(unsigned)ret_type]};
str += &quot; &quot;;
str += std_name;
str += &quot;(&quot;;
bool add_comma = false;
for (const auto&amp; param : params) {
if (add_comma) {
str += &quot;, &quot;;
}
if (param.optional) {
str += &quot;[&quot;;
}
param.allowed_types.to_stdstr(str);
if (param.optional) {
str += &quot;]&quot;;
}
add_comma = true;
}
if (unlim_params) {
if (add_comma) {
str += &quot;, &quot;;
}
str += &quot;...&quot;;
}
str += &quot;)&quot;;
//std::cout &lt;&lt; &quot;Len=&quot; &lt;&lt; str.length() &lt;&lt; &quot;, Cap=&quot; &lt;&lt; str.capacity() &lt;&lt; &quot;\n&quot;;
return str;
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Обыденная задача, подобные часто могут встретится в работе:
По неким данным сгенерировать текст. В этом случае по данным
о неких функциях сформировать их полное имя с типами параметров и
возвращаемого значения. Алгоритм на std::string.
A common task, similar to this one, can often be encountered in work:
Generate text from given data. In this case, using data
on certain functions, generate their full names with parameter types and
return values. The algorithm uses std::string.</span></span></td><td class="benchmarkresult">673</td><td class="benchmarkresult">1021</td><td class="benchmarkresult">738</td><td class="benchmarkresult">1507</td><td class="benchmarkresult">1622</td><td class="benchmarkresult">3162</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2460">Build func full name std::string 1;</a><span class="tooltiptext code">std::string build_full_name_std1() const {
std::string str{has_ret_type_resolver ? &quot;any&quot;sv : type_names_sv[(unsigned)ret_type]};
str += &quot; &quot; + std_name + &quot;(&quot;;
bool add_comma = false;
for (const auto&amp; param : params) {
if (add_comma) {
str += &quot;, &quot;;
}
if (param.optional) {
str += &quot;[&quot;;
}
param.allowed_types.to_stdstr(str);
if (param.optional) {
str += &quot;]&quot;;
}
add_comma = true;
}
if (unlim_params) {
if (add_comma) {
str += &quot;, &quot;;
}
str += &quot;...&quot;;
}
str += &quot;)&quot;;
//std::cout &lt;&lt; &quot;Len=&quot; &lt;&lt; str.length() &lt;&lt; &quot;, Cap=&quot; &lt;&lt; str.capacity() &lt;&lt; &quot;\n&quot;;
return str;
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Почти тот же алгоритм, но несколько последовательных
+= к строке заменены на одно += + + +.
Almost the same algorithm, but several consecutive
+= to a string are replaced with a single += + + +.</span></span></td><td class="benchmarkresult">768</td><td class="benchmarkresult">1021</td><td class="benchmarkresult">820</td><td class="benchmarkresult">1515</td><td class="benchmarkresult">1697</td><td class="benchmarkresult">3363</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2490">Build func full name std::stream;</a><span class="tooltiptext code">std::string build_full_name_stream() const {
std::ostringstream str;
if (has_ret_type_resolver) {
str &lt;&lt; &quot;any&quot;;
} else {
str &lt;&lt; type_names_sv[(unsigned)ret_type];
}
str &lt;&lt; &quot; &quot; &lt;&lt; std_name &lt;&lt; &quot;(&quot;;
bool add_comma = false;
for (const auto&amp; param : params) {
if (add_comma) {
str &lt;&lt; &quot;, &quot;;
}
if (param.optional) {
str &lt;&lt; &quot;[&quot;;
}
param.allowed_types.to_stream(str);
if (param.optional) {
str &lt;&lt; &quot;]&quot;;
}
add_comma = true;
}
if (unlim_params) {
if (add_comma) {
str &lt;&lt; &quot;, &quot;;
}
str &lt;&lt; &quot;...&quot;;
}
str &lt;&lt; &quot;)&quot;;
return str.str();
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Строим имя функции через std::ostringstream и <<
We construct the function name through std::ostringstream and <<</span></span></td><td class="benchmarkresult">3165</td><td class="benchmarkresult">2984</td><td class="benchmarkresult">2610</td><td class="benchmarkresult">8296</td><td class="benchmarkresult">9698</td><td class="benchmarkresult">11876</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2401">Build func full name stringa;</a><span class="tooltiptext code">stringa build_full_name() const {
lstringa&lt;512> str = e_choice(has_ret_type_resolver, &quot;any&quot;, type_names[(unsigned)ret_type]) + &quot; &quot; + name + &quot;(&quot;;
bool add_comma = false;
for (const auto&amp; param : params) {
str += e_if(add_comma, &quot;, &quot;) + e_if(param.optional, &quot;[&quot;);
param.allowed_types.to_simstr(str);
if (param.optional) {
str += &quot;]&quot;;
}
add_comma = true;
}
return str + e_if(unlim_params, e_if(add_comma, &quot;, &quot;) + &quot;...&quot;) + &quot;)&quot;;
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Реализация на simstr строках и строковых выражениях.
Инфа о параметрах добавляется в текущую строку
Implementation using simstr strings and string expressions.
Parameter information is appended to the current line.</span></span></td><td class="benchmarkresult">472</td><td class="benchmarkresult">471</td><td class="benchmarkresult">480</td><td class="benchmarkresult">749</td><td class="benchmarkresult">867</td><td class="benchmarkresult">1461</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2416">Build func full name stringa 1;</a><span class="tooltiptext code">stringa build_full_name1() const {
lstringa&lt;512> str = e_choice(has_ret_type_resolver, &quot;any&quot;, type_names[(unsigned)ret_type]) + &quot; &quot; + name + &quot;(&quot;;
bool add_comma = false;
for (const auto&amp; param : params) {
str += e_if(add_comma, &quot;, &quot;) + e_if(param.optional, &quot;[&quot;) + param.allowed_types.get_simstr() + e_if(param.optional, &quot;]&quot;);
add_comma = true;
}
return str + e_if(unlim_params, e_if(add_comma, &quot;, &quot;) + &quot;...&quot;) + &quot;)&quot;;
}</span></span></td><td><span class="tooltip info">&nbsp;>>&nbsp;<span class="tooltiptext">Реализация на simstr строках и строковых выражениях.
Инфа о параметрах добавляется во временную строку, а потом
разом добавляется в текущую строку. Позволяет операции в цикле
записать в одну строку, но чуть проигрывает по времени выполнения.
Implementation using simstr strings and string expressions.
Parameter information is added to a temporary string, and then
all at once to the current string. This allows loop operations
to be written in a single string, but is slightly slower in execution time.</span></span></td><td class="benchmarkresult">616</td><td class="benchmarkresult">648</td><td class="benchmarkresult">564</td><td class="benchmarkresult">878</td><td class="benchmarkresult">996</td><td class="benchmarkresult">1910</td></tr>
</tbody></table></div><script>bench_sets['Build Full Func Name'] = {id:'bs31', tests:[
{name:'Build func full name std::string;',data:[673,1021,738,1507,1622,3162]},
{name:'Build func full name std::string 1;',data:[768,1021,820,1515,1697,3363]},
{name:'Build func full name std::stream;',data:[3165,2984,2610,8296,9698,11876]},
{name:'Build func full name stringa;',data:[472,471,480,749,867,1461]},
{name:'Build func full name stringa 1;',data:[616,648,564,878,996,1910]}
]}</script>
<div class="benchset" id="bs32"><h4><a id="bs36691618230457010710" href="#bs36691618230457010710">#</a>&nbsp;Make Upper</h4>
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2630">To upper case std::wstring</a><span class="tooltiptext code">void UpperCaseStd(benchmark::State&amp; state) {
static const auto&amp; loc = std::locale(&quot;en_US.utf8&quot;);
for (auto _: state) {
std::wstring test = L&quot;TestПриветTest&quot;;
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&quot;TESTПРИВЕТTEST&quot;) {
state.SkipWithError(&quot;Bad upper case&quot;);
}
#endif
}
}</span></span></td><td></td><td class="benchmarkresult">162</td><td class="benchmarkresult">175</td><td class="benchmarkresult">175</td><td class="benchmarkresult">1457</td><td class="benchmarkresult">1438</td><td class="benchmarkresult">204</td></tr>
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2650">To upper case lstringw&lt;15></a><span class="tooltiptext code">void UpperCaseSim(benchmark::State&amp; state) {
for (auto _: state) {
lstringw&lt;15> test = L&quot;TestПриветTest&quot;;
benchmark::DoNotOptimize(test);
test.upper();
benchmark::DoNotOptimize(test);
#ifdef CHECK_RESULT
if (test != L&quot;TESTПРИВЕТTEST&quot;) {
state.SkipWithError(&quot;Bad upper case&quot;);
}
#endif
}
}</span></span></td><td></td><td class="benchmarkresult">43.7</td><td class="benchmarkresult">38.5</td><td class="benchmarkresult">40.4</td><td class="benchmarkresult">41.0</td><td class="benchmarkresult">44.4</td><td class="benchmarkresult">63.1</td></tr>
</tbody></table></div><script>bench_sets['Make Upper'] = {id:'bs32', tests:[
{name:'To upper case std::wstring',data:[162,175,175,1457,1438,204]},
{name:'To upper case lstringw<15>',data:[43.7,38.5,40.4,41.0,44.4,63.1]}
]}</script></body></html>