2025-04-05 14:21:11 +00:00
< html >
< head >
< meta charset = "UTF-8" / >
< link href = "results.css" rel = "stylesheet" / >
< title > SimStr benchmarks results< / title >
< link rel = "stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" >
< script src = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" > < / script >
< script src = "https://cdn.jsdelivr.net/npm/chart.js" > < / script >
< script >
let bench_sets = {};
let activeBuilder = buildTestsByPlatformsBar;
let buildAsLine = {
"Copy not literal Str with N symbols": "Length of the copied string",
"Replace All Str To Longer Size": "Length of the string to be replaced",
"Replace All Str To Same Size": "Length of the string to be replaced"
};
function hl() {
document.querySelectorAll('.tooltiptext.code').forEach((el) => {
hljs.highlightElement(el);
});
}
function addBarChart(id, data) {
let canvas = document.getElementById('chart' + id);
new Chart(canvas, {
type: 'bar',
data: data,
options: {
scales: {
y: {
beginAtZero: true
},
x: {
title: {
text: "Time (ns)",
display: true
}
}
},
indexAxis: 'y',
plugins: {
legend: {
position: 'right',
labels: {
font: {
family: "'Cascadia Code', Consolas, 'Courier New', Courier, monospace"
}
}
}
}
}
});
}
function platformChecked(idx) {
return document.getElementById('pl' + idx).checked;
}
function buildPlatformsByTestsBar(bsName) {
if (buildAsLine[bsName]) {
buildPlatformsByTestsLine(bsName, buildAsLine[bsName]);
return;
}
let data = { labels: [], datasets: [] };
for (const i in platform_names) {
if (platformChecked(i))
data.datasets.push({ label: platform_names[i], data: [], borderWidth: 1 });
}
let bs = bench_sets[bsName];
for (const test of bs.tests) {
data.labels.push(test.name);
let ds = 0;
for (const i in test.data) {
if (platformChecked(i)) {
data.datasets[ds++].data.push(test.data[i]);
}
}
}
addBarChart(bs.id, data);
}
function buildTestsByPlatformsBar(bsName) {
if (buildAsLine[bsName], buildAsLine[bsName]) {
buildTestsByPlatformsLine(bsName, buildAsLine[bsName]);
return;
}
let data = { labels: [], datasets: [] };
let bs = bench_sets[bsName];
for (const test of bs.tests) {
data.datasets.push({ label: test.name, data: [], borderWidth: 1 });
}
for (const i in platform_names) {
if (platformChecked(i)) {
data.labels.push(platform_names[i]);
for (const j in bs.tests) {
data.datasets[j].data.push(bs.tests[j].data[i]);
}
}
}
addBarChart(bs.id, data);
}
function buildCanvas(plCount) {
document.querySelectorAll("canvas.bench_chart").forEach(e => e.remove());
for (var bs_name in bench_sets) {
let bs = bench_sets[bs_name];
if (plCount) {
let canvas = document.createElement('canvas');
canvas.id = "chart" + bs.id;
canvas.classList.add('bench_chart');
let h = 20 * plCount * bs.tests.length;
canvas.style.width = "100%";
canvas.style.height = h + "px";
canvas.height = h * devicePixelRatio;
document.getElementById(bs.id).after(canvas);
}
}
}
function addLineChart(canvas, data, title, scaleTitle) {
new Chart(canvas, {
type: 'line',
data: data,
options: {
scales: {
y: {
beginAtZero: true,
title: {
text: scaleTitle,
display: true
}
},
x: {
title: {
text: "Time (ns)",
display: true
}
}
},
indexAxis: 'y',
plugins: {
title: {
display: true,
text: title,
},
legend: {
position: 'right',
labels: {
font: {
family: "'Cascadia Code', Consolas, 'Courier New', Courier, monospace"
}
}
}
}
}
});
}
function buildTestsByPlatformsLineOne(bs, canvas, plIdx, scaleTitle) {
let data = { datasets: [] };
let prevTest = '';
let curData = undefined;
for (const test of bs.tests) {
let m = test.name.match(/(.+)[\/\|](\d+)$/);
if (m[1] != prevTest) {
prevTest = m[1];
curData = { label: prevTest, data: [], borderWidth: 1 };
data.datasets.push(curData);
}
curData.data.push([test.data[plIdx], m[2]]);
}
addLineChart(canvas, data, platform_names[plIdx], scaleTitle);
}
function buildTestsByPlatformsLine(bsName, scaleTitle) {
let bs = bench_sets[bsName];
let canvas = document.getElementById('chart' + bs.id);
let after = null;
for (const i in platform_names) {
if (platformChecked(i)) {
if (!canvas) {
canvas = document.createElement('canvas');
canvas.classList.add('bench_chart');
canvas.style.width = "100%";
after.after(canvas);
}
canvas.style.height = "300px";
canvas.height = 300 * devicePixelRatio;
buildTestsByPlatformsLineOne(bs, canvas, i, scaleTitle);
after = canvas;
canvas = null;
}
}
}
function buildPlatformsByTestsLineOne(bs, canvas, after, testData, title, scaleTitle) {
let data = { datasets: [] };
for (const i in platform_names) {
if (platformChecked(i)) {
ds = {label: platform_names[i], data: []};
for (const test of testData) {
ds.data.push([test.data[i], test.count]);
}
data.datasets.push(ds);
}
}
if (!canvas) {
canvas = document.createElement('canvas');
canvas.classList.add('bench_chart');
canvas.style.width = "100%";
after.after(canvas);
}
canvas.style.height = "300px";
canvas.height = 300 * devicePixelRatio;
addLineChart(canvas, data, title, scaleTitle);
return canvas;
}
function buildPlatformsByTestsLine(bsName, scaleTitle) {
let bs = bench_sets[bsName];
let canvas = document.getElementById('chart' + bs.id);
let after = null;
let data = [];
let prevTest = '';
for (const test of bs.tests) {
let m = test.name.match(/(.+)[\/\|](\d+)$/);
if (m[1] != prevTest) {
if (data.length) {
after = buildPlatformsByTestsLineOne(bs, canvas, after, data, prevTest, scaleTitle);
canvas = null;
}
prevTest = m[1];
data = [];
}
data.push({count: m[2], data: test.data});
}
if (data.length) {
buildPlatformsByTestsLineOne(bs, canvas, after, data, prevTest, scaleTitle);
}
}
function buildCharts() {
let plCount = 0;
for (const i in platform_names) {
if (platformChecked(i))
plCount++;
}
buildCanvas(plCount);
for (var bs_name in bench_sets) {
activeBuilder(bs_name);
}
}
function switchGrouping() {
activeBuilder = document.getElementById('gbp').checked ? buildTestsByPlatformsBar : buildPlatformsByTestsBar;
buildCharts();
}
document.addEventListener('DOMContentLoaded', (event) => {
if (!hljs) {
let scriptTag = document.createElement('script');
scriptTag.src = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js";
scriptTag.onload = hl;
scriptTag.onreadystatechange = hl;
document.body.appendChild(scriptTag);
} else {
hl();
}
if (!Chart) {
let scriptTag = document.createElement('script');
scriptTag.src = "https://cdn.jsdelivr.net/npm/chart.js";
scriptTag.onload = buildCharts;
scriptTag.onreadystatechange = buildCharts;
document.body.appendChild(scriptTag);
} else {
buildCharts();
}
});
< / script >
< / head > < body > < div class = "header" > < h2 > SimStr benchmarks results< / h2 >
< span > All times in ns.< / span >
< span > < a href = "https://github.com/orefkov/simstr/blob/main/bench/bench_str.cpp" > Source for benchmarks< / a > < / span >
< 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-21< / 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)
2025-11-26 19:15:50 +00:00
Load Average: 0.10, 0.62, 0.73< / span > < / span > Include in charts: < input type = "checkbox" id = "pl0" checked onchange = "buildCharts()" / > < / li >
2025-04-05 14:21:11 +00:00
< li > < span class = "platform" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / 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)
2025-11-26 19:15:50 +00:00
Load Average: 0.02, 0.05, 0.12< / span > < / span > Include in charts: < input type = "checkbox" id = "pl1" checked onchange = "buildCharts()" / > < / li >
< li > < span class = "platform" > Xeon E5-2682 v4, Windows 10, Clang-19< / span > < span class = "tooltip" > 32 X 2494 MHz CPU s< span class = "tooltiptext" > CPU Caches:
2025-04-05 14:21:11 +00:00
L1 Data 32 KiB (x16)
L1 Instruction 32 KiB (x16)
L2 Unified 256 KiB (x16)
L3 Unified 40960 KiB (x1)< / span > < / span > Include in charts: < input type = "checkbox" id = "pl2" checked onchange = "buildCharts()" / > < / li >
2025-11-26 19:15:50 +00:00
< 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:
2025-04-05 14:21:11 +00:00
L1 Data 32 KiB (x16)
L1 Instruction 32 KiB (x16)
L2 Unified 256 KiB (x16)
L3 Unified 40960 KiB (x1)< / span > < / span > Include in charts: < input type = "checkbox" id = "pl3" checked onchange = "buildCharts()" / > < / li >
2025-11-26 19:15:50 +00:00
< li > < span class = "platform" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / span > < span class = "tooltip" > 32 X 2513.96 MHz CPU s< span class = "tooltiptext" > Chromium: 142.0.7444.60 webasm< / span > < / span > Include in charts: < input type = "checkbox" id = "pl4" checked onchange = "buildCharts()" / > < / li >
2025-04-05 14:21:11 +00:00
< / ul > < / div > < / div >
< script > const platform _names = [ 'Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21' , 'Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13' , 'Xeon E5-2682 v4, Windows 10, Clang-19' , 'Xeon E5-2682 v4, Windows 10, MSVC-19' , 'Xeon E5-2682 v4, WASM Chrome, Clang-21' ] ; < / script >
< div class = "benchset" id = "bs1" > < h4 > Create Empty Str< / h4 >
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string e;< span class = "tooltiptext code" > template< typename T>
void CreateEmpty(benchmark::State& state) {
for (auto _: state) {
T empty_string;
benchmark::DoNotOptimize(empty_string);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Пустые строки, ничего необычного.< / span > < / span > < / td > < td class = "benchmarkresult" > 1.11< / td > < td class = "benchmarkresult" > 1.15< / td > < td class = "benchmarkresult" > 1.11< / td > < td class = "benchmarkresult" > 2.95< / td > < td class = "benchmarkresult" > 5.87< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string_view e;< span class = "tooltiptext code" > template< typename T>
void CreateEmpty(benchmark::State& state) {
for (auto _: state) {
T empty_string;
benchmark::DoNotOptimize(empty_string);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 0.369< / td > < td class = "benchmarkresult" > 0.743< / td > < td class = "benchmarkresult" > 0.368< / td > < td class = "benchmarkresult" > 1.85< / td > < td class = "benchmarkresult" > 5.26< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > ssa e;< span class = "tooltiptext code" > template< typename T>
void CreateEmpty(benchmark::State& state) {
for (auto _: state) {
T empty_string;
benchmark::DoNotOptimize(empty_string);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 0.369< / td > < td class = "benchmarkresult" > 0.185< / td > < td class = "benchmarkresult" > 0.361< / td > < td class = "benchmarkresult" > 1.52< / td > < td class = "benchmarkresult" > 4.67< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa e;< span class = "tooltiptext code" > template< typename T>
void CreateEmpty(benchmark::State& state) {
for (auto _: state) {
T empty_string;
benchmark::DoNotOptimize(empty_string);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 0.742< / td > < td class = "benchmarkresult" > 0.759< / td > < td class = "benchmarkresult" > 0.736< / td > < td class = "benchmarkresult" > 2.25< / td > < td class = "benchmarkresult" > 4.82< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 20> e;< span class = "tooltiptext code" > template< typename T>
void CreateEmpty(benchmark::State& state) {
for (auto _: state) {
T empty_string;
benchmark::DoNotOptimize(empty_string);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1.13< / td > < td class = "benchmarkresult" > 1.13< / td > < td class = "benchmarkresult" > 1.12< / td > < td class = "benchmarkresult" > 2.58< / td > < td class = "benchmarkresult" > 4.64< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 40> e;< span class = "tooltiptext code" > template< typename T>
void CreateEmpty(benchmark::State& state) {
for (auto _: state) {
T empty_string;
benchmark::DoNotOptimize(empty_string);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1.13< / td > < td class = "benchmarkresult" > 1.13< / td > < td class = "benchmarkresult" > 1.13< / td > < td class = "benchmarkresult" > 2.59< / td > < td class = "benchmarkresult" > 4.76< / td > < / tr >
2025-04-05 14:21:11 +00:00
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' C r e a t e E m p t y S t r ' ] = { i d : ' b s 1 ' , t e s t s : [
2025-11-26 19:15:50 +00:00
{name:'std::string e;',data:[1.11,1.15,1.11,2.95,5.87]},
{name:'std::string_view e;',data:[0.369,0.743,0.368,1.85,5.26]},
{name:'ssa e;',data:[0.369,0.185,0.361,1.52,4.67]},
{name:'stringa e;',data:[0.742,0.759,0.736,2.25,4.82]},
{name:'lstringa< 20 > e;',data:[1.13,1.13,1.12,2.58,4.64]},
{name:'lstringa< 40 > e;',data:[1.13,1.13,1.13,2.59,4.76]}
2025-04-05 14:21:11 +00:00
]}< / script >
< div class = "benchset" id = "bs2" > < h4 > Create Str from short literal (9 symbols)< / h4 >
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string e = " Test text" ;< span class = "tooltiptext code" > template< typename T>
void CreateShortLiteral(benchmark::State& state) {
for (auto _: state) {
T empty_string = TEST_TEXT;
benchmark::DoNotOptimize(empty_string);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Короткий литерал помещается во внутренний буфер std::string,
2025-11-26 19:15:50 +00:00
время тратится только на копирование 10 байтов.< / span > < / span > < / td > < td class = "benchmarkresult" > 1.91< / td > < td class = "benchmarkresult" > 1.85< / td > < td class = "benchmarkresult" > 1.87< / td > < td class = "benchmarkresult" > 2.58< / td > < td class = "benchmarkresult" > 5.17< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string_view e = " Test text" ;< span class = "tooltiptext code" > template< typename T>
void CreateShortLiteral(benchmark::State& state) {
for (auto _: state) {
T empty_string = TEST_TEXT;
benchmark::DoNotOptimize(empty_string);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > И string_view, и ssa - по сути одно и то же:
2025-11-26 19:15:50 +00:00
указатель на текст и е г о длина.< / span > < / span > < / td > < td class = "benchmarkresult" > 0.748< / td > < td class = "benchmarkresult" > 0.751< / td > < td class = "benchmarkresult" > 0.727< / td > < td class = "benchmarkresult" > 1.90< / td > < td class = "benchmarkresult" > 5.57< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > ssa e = " Test text" ;< span class = "tooltiptext code" > template< typename T>
void CreateShortLiteral(benchmark::State& state) {
for (auto _: state) {
T empty_string = TEST_TEXT;
benchmark::DoNotOptimize(empty_string);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 0.374< / td > < td class = "benchmarkresult" > 0.781< / td > < td class = "benchmarkresult" > 0.364< / td > < td class = "benchmarkresult" > 1.85< / td > < td class = "benchmarkresult" > 3.41< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa e = " Test text" ;< span class = "tooltiptext code" > template< typename T>
void CreateShortLiteral(benchmark::State& state) {
for (auto _: state) {
T empty_string = TEST_TEXT;
benchmark::DoNotOptimize(empty_string);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > stringa при инициализации константным литералом так же
2025-11-26 19:15:50 +00:00
сохраняет только указатель на текст и е г о длину.< / span > < / span > < / td > < td class = "benchmarkresult" > 1.11< / td > < td class = "benchmarkresult" > 1.13< / td > < td class = "benchmarkresult" > 1.10< / td > < td class = "benchmarkresult" > 2.92< / td > < td class = "benchmarkresult" > 5.07< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 20> e = " Test text" ;< span class = "tooltiptext code" > template< typename T>
void CreateShortLiteral(benchmark::State& state) {
for (auto _: state) {
T empty_string = TEST_TEXT;
benchmark::DoNotOptimize(empty_string);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Внутреннего буфера хватает для размещения символов,
2025-11-26 19:15:50 +00:00
время уходит только на копирование байтов.< / span > < / span > < / td > < td class = "benchmarkresult" > 1.88< / td > < td class = "benchmarkresult" > 1.86< / td > < td class = "benchmarkresult" > 1.85< / td > < td class = "benchmarkresult" > 2.59< / td > < td class = "benchmarkresult" > 5.37< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 40> e = " Test text" ;< span class = "tooltiptext code" > template< typename T>
void CreateShortLiteral(benchmark::State& state) {
for (auto _: state) {
T empty_string = TEST_TEXT;
benchmark::DoNotOptimize(empty_string);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1.86< / td > < td class = "benchmarkresult" > 1.88< / td > < td class = "benchmarkresult" > 1.84< / td > < td class = "benchmarkresult" > 2.61< / td > < td class = "benchmarkresult" > 5.37< / td > < / tr >
2025-04-05 14:21:11 +00:00
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' C r e a t e S t r f r o m s h o r t l i t e r a l ( 9 s y m b o l s ) ' ] = { i d : ' b s 2 ' , t e s t s : [
2025-11-26 19:15:50 +00:00
{name:'std::string e = "Test text";',data:[1.91,1.85,1.87,2.58,5.17]},
{name:'std::string_view e = "Test text";',data:[0.748,0.751,0.727,1.90,5.57]},
{name:'ssa e = "Test text";',data:[0.374,0.781,0.364,1.85,3.41]},
{name:'stringa e = "Test text";',data:[1.11,1.13,1.10,2.92,5.07]},
{name:'lstringa< 20 > e = "Test text";',data:[1.88,1.86,1.85,2.59,5.37]},
{name:'lstringa< 40 > e = "Test text";',data:[1.86,1.88,1.84,2.61,5.37]}
2025-04-05 14:21:11 +00:00
]}< / script >
< div class = "benchset" id = "bs3" > < h4 > Create Str from long literal (30 symbols)< / h4 >
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string e = " 123456789012345678901234567890" ;< span class = "tooltiptext code" > template< typename T>
void CreateLongLiteral(benchmark::State& state) {
for (auto _: state) {
T empty_string{LONG_TEXT};
benchmark::DoNotOptimize(empty_string);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Вот тут уже литерал не помещается во внутренний буфер,
возникает аллокация и копирование 30-и байтов.
2025-11-26 19:15:50 +00:00
Н о как же отстает аллокация под Windows от Linux'а , 20 vs 70 ns...< / span > < / span > < / td > < td class = "benchmarkresult" > 18.8< / td > < td class = "benchmarkresult" > 19.9< / td > < td class = "benchmarkresult" > 78.5< / td > < td class = "benchmarkresult" > 76.0< / td > < td class = "benchmarkresult" > 63.4< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string_view e = " 123456789012345678901234567890" ;< span class = "tooltiptext code" > template< typename T>
void CreateLongLiteral(benchmark::State& state) {
for (auto _: state) {
T empty_string{LONG_TEXT};
benchmark::DoNotOptimize(empty_string);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > string_view и ssa по прежнему ничего не делают, кроме
2025-11-26 19:15:50 +00:00
запоминания указателя на текст и е г о размера.< / span > < / span > < / td > < td class = "benchmarkresult" > 0.747< / td > < td class = "benchmarkresult" > 0.808< / td > < td class = "benchmarkresult" > 0.731< / td > < td class = "benchmarkresult" > 1.82< / td > < td class = "benchmarkresult" > 5.58< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > ssa e = " 123456789012345678901234567890" ;< span class = "tooltiptext code" > template< typename T>
void CreateLongLiteral(benchmark::State& state) {
for (auto _: state) {
T empty_string{LONG_TEXT};
benchmark::DoNotOptimize(empty_string);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 0.373< / td > < td class = "benchmarkresult" > 0.754< / td > < td class = "benchmarkresult" > 0.371< / td > < td class = "benchmarkresult" > 1.82< / td > < td class = "benchmarkresult" > 3.33< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa e = " 123456789012345678901234567890" ;< span class = "tooltiptext code" > template< typename T>
void CreateLongLiteral(benchmark::State& state) {
for (auto _: state) {
T empty_string{LONG_TEXT};
benchmark::DoNotOptimize(empty_string);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > stringa на константных литералах не отстает!< / span > < / span > < / td > < td class = "benchmarkresult" > 1.13< / td > < td class = "benchmarkresult" > 1.12< / td > < td class = "benchmarkresult" > 1.12< / td > < td class = "benchmarkresult" > 2.58< / td > < td class = "benchmarkresult" > 4.95< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 20> e = " 123456789012345678901234567890" ;< span class = "tooltiptext code" > template< typename T>
void CreateLongLiteral(benchmark::State& state) {
for (auto _: state) {
T empty_string{LONG_TEXT};
benchmark::DoNotOptimize(empty_string);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > lstringa< 20 > может вместить в себя до 23 символов,
2025-11-26 19:15:50 +00:00
Очевидно, что для 30-и символов уже нужна аллокация.< / span > < / span > < / td > < td class = "benchmarkresult" > 21.2< / td > < td class = "benchmarkresult" > 19.6< / td > < td class = "benchmarkresult" > 80.1< / td > < td class = "benchmarkresult" > 76.8< / td > < td class = "benchmarkresult" > 63.1< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 40> e = " 123456789012345678901234567890" ;< span class = "tooltiptext code" > template< typename T>
void CreateLongLiteral(benchmark::State& state) {
for (auto _: state) {
T empty_string{LONG_TEXT};
benchmark::DoNotOptimize(empty_string);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > А в lstringa< 40 > влезает до 47 символов, так что просто
2025-11-26 19:15:50 +00:00
копируется 30 байтов.< / span > < / span > < / td > < td class = "benchmarkresult" > 2.57< / td > < td class = "benchmarkresult" > 1.86< / td > < td class = "benchmarkresult" > 2.53< / td > < td class = "benchmarkresult" > 3.33< / td > < td class = "benchmarkresult" > 5.86< / td > < / tr >
2025-04-05 14:21:11 +00:00
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' C r e a t e S t r f r o m l o n g l i t e r a l ( 3 0 s y m b o l s ) ' ] = { i d : ' b s 3 ' , t e s t s : [
2025-11-26 19:15:50 +00:00
{name:'std::string e = "123456789012345678901234567890";',data:[18.8,19.9,78.5,76.0,63.4]},
{name:'std::string_view e = "123456789012345678901234567890";',data:[0.747,0.808,0.731,1.82,5.58]},
{name:'ssa e = "123456789012345678901234567890";',data:[0.373,0.754,0.371,1.82,3.33]},
{name:'stringa e = "123456789012345678901234567890";',data:[1.13,1.12,1.12,2.58,4.95]},
{name:'lstringa< 20 > e = "123456789012345678901234567890";',data:[21.2,19.6,80.1,76.8,63.1]},
{name:'lstringa< 40 > e = "123456789012345678901234567890";',data:[2.57,1.86,2.53,3.33,5.86]}
2025-04-05 14:21:11 +00:00
]}< / script >
< div class = "benchset" id = "bs4" > < h4 > Create copy of Str with 9 symbols< / h4 >
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string e = " Test text" ; auto c{e};< span class = "tooltiptext code" > template< typename T>
void CopyShortString(benchmark::State& state) {
T x{TEST_TEXT};
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Строка в пределах SSO, так что просто копирует байты.< / span > < / span > < / td > < td class = "benchmarkresult" > 4.98< / td > < td class = "benchmarkresult" > 4.95< / td > < td class = "benchmarkresult" > 1.85< / td > < td class = "benchmarkresult" > 6.00< / td > < td class = "benchmarkresult" > 11.0< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string_view e = " Test text" ; auto c{e};< span class = "tooltiptext code" > template< typename T>
void CopyShortString(benchmark::State& state) {
T x{TEST_TEXT};
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 0.373< / td > < td class = "benchmarkresult" > 0.381< / td > < td class = "benchmarkresult" > 0.370< / td > < td class = "benchmarkresult" > 3.46< / td > < td class = "benchmarkresult" > 5.91< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > ssa e = " Test text" ; auto c{e};< span class = "tooltiptext code" > template< typename T>
void CopyShortString(benchmark::State& 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" > >> < span class = "tooltiptext" > ssa и string_view не владеют строкой, копируется
2025-11-26 19:15:50 +00:00
только информация о строке.< / span > < / span > < / td > < td class = "benchmarkresult" > 0.376< / td > < td class = "benchmarkresult" > 0.377< / td > < td class = "benchmarkresult" > 0.370< / td > < td class = "benchmarkresult" > 3.51< / td > < td class = "benchmarkresult" > 6.84< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa e = " Test text" ; auto c{e};< span class = "tooltiptext code" > template< typename T>
void CopyShortString(benchmark::State& 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" > >> < span class = "tooltiptext" > Копирование stringa происходит быстро,
2025-11-26 19:15:50 +00:00
особенно если она инициализирована литералом.< / span > < / span > < / td > < td class = "benchmarkresult" > 1.13< / td > < td class = "benchmarkresult" > 1.35< / td > < td class = "benchmarkresult" > 1.30< / td > < td class = "benchmarkresult" > 4.03< / td > < td class = "benchmarkresult" > 5.18< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 20> e = " Test text" ; auto c{e};< span class = "tooltiptext code" > template< typename T>
void CopyShortString(benchmark::State& state) {
T x{TEST_TEXT};
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > В обоих случаях хватает внутреннего буфера.< / span > < / span > < / td > < td class = "benchmarkresult" > 4.84< / td > < td class = "benchmarkresult" > 4.49< / td > < td class = "benchmarkresult" > 5.25< / td > < td class = "benchmarkresult" > 8.51< / td > < td class = "benchmarkresult" > 17.5< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 40> e = " Test text" ; auto c{e};< span class = "tooltiptext code" > template< typename T>
void CopyShortString(benchmark::State& state) {
T x{TEST_TEXT};
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Только копируются байты.< / span > < / span > < / td > < td class = "benchmarkresult" > 4.53< / td > < td class = "benchmarkresult" > 4.93< / td > < td class = "benchmarkresult" > 5.36< / td > < td class = "benchmarkresult" > 8.43< / td > < td class = "benchmarkresult" > 17.4< / td > < / tr >
2025-04-05 14:21:11 +00:00
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' C r e a t e c o p y o f S t r w i t h 9 s y m b o l s ' ] = { i d : ' b s 4 ' , t e s t s : [
2025-11-26 19:15:50 +00:00
{name:'std::string e = "Test text"; auto c{e};',data:[4.98,4.95,1.85,6.00,11.0]},
{name:'std::string_view e = "Test text"; auto c{e};',data:[0.373,0.381,0.370,3.46,5.91]},
{name:'ssa e = "Test text"; auto c{e};',data:[0.376,0.377,0.370,3.51,6.84]},
{name:'stringa e = "Test text"; auto c{e};',data:[1.13,1.35,1.30,4.03,5.18]},
{name:'lstringa< 20 > e = "Test text"; auto c{e};',data:[4.84,4.49,5.25,8.51,17.5]},
{name:'lstringa< 40 > e = "Test text"; auto c{e};',data:[4.53,4.93,5.36,8.43,17.4]}
2025-04-05 14:21:11 +00:00
]}< / script >
< div class = "benchset" id = "bs5" > < h4 > Create copy of Str with 30 symbols< / h4 >
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string e = " 123456789012345678901234567890" ; auto c{e};< span class = "tooltiptext code" > template< typename T>
void CopyLongString(benchmark::State& state) {
T x = LONG_TEXT;
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Копирования длинной строки вызывает аллокацию,
2025-11-26 19:15:50 +00:00
SSO уже не хватает. И снова как же отстаёт аллокация под Windows...< / span > < / span > < / td > < td class = "benchmarkresult" > 19.6< / td > < td class = "benchmarkresult" > 24.2< / td > < td class = "benchmarkresult" > 81.7< / td > < td class = "benchmarkresult" > 83.0< / td > < td class = "benchmarkresult" > 93.3< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string_view e = " 123456789012345678901234567890" ; auto c{e};< span class = "tooltiptext code" > template< typename T>
void CopyLongString(benchmark::State& state) {
T x = LONG_TEXT;
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 0.748< / td > < td class = "benchmarkresult" > 0.747< / td > < td class = "benchmarkresult" > 0.741< / td > < td class = "benchmarkresult" > 1.90< / td > < td class = "benchmarkresult" > 5.57< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > ssa e = " 123456789012345678901234567890" ; auto c{e};< span class = "tooltiptext code" > template< typename T>
void CopyLongString(benchmark::State& state) {
T x = LONG_TEXT;
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 0.373< / td > < td class = "benchmarkresult" > 0.746< / td > < td class = "benchmarkresult" > 0.368< / td > < td class = "benchmarkresult" > 2.02< / td > < td class = "benchmarkresult" > 3.32< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa e = " 123456789012345678901234567890" ; auto c{e};< span class = "tooltiptext code" > template< typename T>
void CopyLongString(benchmark::State& state) {
T x = LONG_TEXT;
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > А вот у stringa копирование литерала не зависит от е г о длины,
2025-11-26 19:15:50 +00:00
сравни с предыдущим бенчмарком.< / span > < / span > < / td > < td class = "benchmarkresult" > 1.13< / td > < td class = "benchmarkresult" > 1.13< / td > < td class = "benchmarkresult" > 1.86< / td > < td class = "benchmarkresult" > 3.41< / td > < td class = "benchmarkresult" > 4.89< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 20> e = " 123456789012345678901234567890" ; auto c{e};< span class = "tooltiptext code" > template< typename T>
void CopyLongString(benchmark::State& state) {
T x = LONG_TEXT;
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Н е влезает, аллокация.< / span > < / span > < / td > < td class = "benchmarkresult" > 20.0< / td > < td class = "benchmarkresult" > 24.4< / td > < td class = "benchmarkresult" > 79.3< / td > < td class = "benchmarkresult" > 90.4< / td > < td class = "benchmarkresult" > 66.3< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 40> e = " 123456789012345678901234567890" ; auto c{e};< span class = "tooltiptext code" > template< typename T>
void CopyLongString(benchmark::State& state) {
T x = LONG_TEXT;
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Уложили во внутренний буфер.< / span > < / span > < / td > < td class = "benchmarkresult" > 5.40< / td > < td class = "benchmarkresult" > 4.61< / td > < td class = "benchmarkresult" > 4.94< / td > < td class = "benchmarkresult" > 7.11< / td > < td class = "benchmarkresult" > 17.0< / td > < / tr >
2025-04-05 14:21:11 +00:00
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' C r e a t e c o p y o f S t r w i t h 3 0 s y m b o l s ' ] = { i d : ' b s 5 ' , t e s t s : [
2025-11-26 19:15:50 +00:00
{name:'std::string e = "123456789012345678901234567890"; auto c{e};',data:[19.6,24.2,81.7,83.0,93.3]},
{name:'std::string_view e = "123456789012345678901234567890"; auto c{e};',data:[0.748,0.747,0.741,1.90,5.57]},
{name:'ssa e = "123456789012345678901234567890"; auto c{e};',data:[0.373,0.746,0.368,2.02,3.32]},
{name:'stringa e = "123456789012345678901234567890"; auto c{e};',data:[1.13,1.13,1.86,3.41,4.89]},
{name:'lstringa< 20 > e = "123456789012345678901234567890"; auto c{e};',data:[20.0,24.4,79.3,90.4,66.3]},
{name:'lstringa< 40 > e = "123456789012345678901234567890"; auto c{e};',data:[5.40,4.61,4.94,7.11,17.0]}
2025-04-05 14:21:11 +00:00
]}< / script >
< div class = "benchset" id = "bs6" > < h4 > 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 = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string::find;< span class = "tooltiptext code" > template< typename T>
void Find(benchmark::State& state) {
T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT};
for (auto _: state) {
int i = (int)x.find(TEST_TEXT);
#ifdef CHECK_RESULT
if (i != 90) {
state.SkipWithError(" not find?" );
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Здесь "победила дружба", у всех типов по колонке примерно одинаково.
2025-11-26 19:15:50 +00:00
Однако, Windows и Linux явно в разных весовых категориях.< / span > < / span > < / td > < td class = "benchmarkresult" > 6.87< / td > < td class = "benchmarkresult" > 6.87< / td > < td class = "benchmarkresult" > 39.5< / td > < td class = "benchmarkresult" > 45.0< / td > < td class = "benchmarkresult" > 101< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string_view::find;< span class = "tooltiptext code" > template< typename T>
void Find(benchmark::State& state) {
T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT};
for (auto _: state) {
int i = (int)x.find(TEST_TEXT);
#ifdef CHECK_RESULT
if (i != 90) {
state.SkipWithError(" not find?" );
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 7.75< / td > < td class = "benchmarkresult" > 7.39< / td > < td class = "benchmarkresult" > 40.0< / td > < td class = "benchmarkresult" > 44.2< / td > < td class = "benchmarkresult" > 103< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > ssa::find;< span class = "tooltiptext code" > template< typename T>
void Find(benchmark::State& state) {
T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT};
for (auto _: state) {
int i = (int)x.find(TEST_TEXT);
#ifdef CHECK_RESULT
if (i != 90) {
state.SkipWithError(" not find?" );
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 6.96< / td > < td class = "benchmarkresult" > 6.93< / td > < td class = "benchmarkresult" > 18.1< / td > < td class = "benchmarkresult" > 21.8< / td > < td class = "benchmarkresult" > 102< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa::find;< span class = "tooltiptext code" > template< typename T>
void Find(benchmark::State& state) {
T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT};
for (auto _: state) {
int i = (int)x.find(TEST_TEXT);
#ifdef CHECK_RESULT
if (i != 90) {
state.SkipWithError(" not find?" );
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 7.38< / td > < td class = "benchmarkresult" > 8.00< / td > < td class = "benchmarkresult" > 19.4< / td > < td class = "benchmarkresult" > 31.0< / td > < td class = "benchmarkresult" > 105< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 20>::find;< span class = "tooltiptext code" > template< typename T>
void Find(benchmark::State& state) {
T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT};
for (auto _: state) {
int i = (int)x.find(TEST_TEXT);
#ifdef CHECK_RESULT
if (i != 90) {
state.SkipWithError(" not find?" );
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 6.90< / td > < td class = "benchmarkresult" > 6.92< / td > < td class = "benchmarkresult" > 18.1< / td > < td class = "benchmarkresult" > 26.3< / td > < td class = "benchmarkresult" > 99.9< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 40>::find;< span class = "tooltiptext code" > template< typename T>
void Find(benchmark::State& state) {
T x{LONG_TEXT LONG_TEXT LONG_TEXT TEST_TEXT};
for (auto _: state) {
int i = (int)x.find(TEST_TEXT);
#ifdef CHECK_RESULT
if (i != 90) {
state.SkipWithError(" not find?" );
break;
}
#endif
benchmark::DoNotOptimize(i);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 6.83< / td > < td class = "benchmarkresult" > 6.87< / td > < td class = "benchmarkresult" > 18.1< / td > < td class = "benchmarkresult" > 24.9< / td > < td class = "benchmarkresult" > 100< / td > < / tr >
2025-04-05 14:21:11 +00:00
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' F i n d 9 s y m b o l s t e x t i n e n d o f 9 9 s y m b o l s t e x t ' ] = { i d : ' b s 6 ' , t e s t s : [
2025-11-26 19:15:50 +00:00
{name:'std::string::find;',data:[6.87,6.87,39.5,45.0,101]},
{name:'std::string_view::find;',data:[7.75,7.39,40.0,44.2,103]},
{name:'ssa::find;',data:[6.96,6.93,18.1,21.8,102]},
{name:'stringa::find;',data:[7.38,8.00,19.4,31.0,105]},
{name:'lstringa< 20 > ::find;',data:[6.90,6.92,18.1,26.3,99.9]},
{name:'lstringa< 40 > ::find;',data:[6.83,6.87,18.1,24.9,100]}
2025-04-05 14:21:11 +00:00
]}< / script >
< div class = "benchset" id = "bs7" > < h4 > Copy not literal Str with N symbols< / h4 >
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string copy{str_with_len_N};/15< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 4.90< / td > < td class = "benchmarkresult" > 5.07< / td > < td class = "benchmarkresult" > 1.86< / td > < td class = "benchmarkresult" > 4.45< / td > < td class = "benchmarkresult" > 97.2< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string copy{str_with_len_N};/16< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Явно виден скачок, где заканчивается SSO и начинается аллокация.
Обратите внимание, что WASM - 32-битный, и там размер
2025-11-26 19:15:50 +00:00
SSO у std::string меньше, насколько я помню, 11 символов + 0.< / span > < / span > < / td > < td class = "benchmarkresult" > 23.1< / td > < td class = "benchmarkresult" > 23.7< / td > < td class = "benchmarkresult" > 81.6< / td > < td class = "benchmarkresult" > 94.0< / td > < td class = "benchmarkresult" > 94.6< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string copy{str_with_len_N};/23< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Дальше просто добавляется время на копирование байтов.< / span > < / span > < / td > < td class = "benchmarkresult" > 23.2< / td > < td class = "benchmarkresult" > 23.9< / td > < td class = "benchmarkresult" > 79.8< / td > < td class = "benchmarkresult" > 94.8< / td > < td class = "benchmarkresult" > 91.6< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string copy{str_with_len_N};/24< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 22.3< / td > < td class = "benchmarkresult" > 24.9< / td > < td class = "benchmarkresult" > 80.5< / td > < td class = "benchmarkresult" > 97.7< / td > < td class = "benchmarkresult" > 94.5< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string copy{str_with_len_N};/32< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 22.2< / td > < td class = "benchmarkresult" > 22.6< / td > < td class = "benchmarkresult" > 86.2< / td > < td class = "benchmarkresult" > 95.8< / td > < td class = "benchmarkresult" > 97.0< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string copy{str_with_len_N};/64< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 22.6< / td > < td class = "benchmarkresult" > 22.9< / td > < td class = "benchmarkresult" > 79.3< / td > < td class = "benchmarkresult" > 94.1< / td > < td class = "benchmarkresult" > 98.1< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string copy{str_with_len_N};/128< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 26.2< / td > < td class = "benchmarkresult" > 24.2< / td > < td class = "benchmarkresult" > 85.0< / td > < td class = "benchmarkresult" > 103< / td > < td class = "benchmarkresult" > 103< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string copy{str_with_len_N};/256< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 27.3< / td > < td class = "benchmarkresult" > 25.5< / td > < td class = "benchmarkresult" > 84.4< / td > < td class = "benchmarkresult" > 105< / td > < td class = "benchmarkresult" > 161< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string copy{str_with_len_N};/512< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 28.3< / td > < td class = "benchmarkresult" > 29.2< / td > < td class = "benchmarkresult" > 86.6< / td > < td class = "benchmarkresult" > 97.1< / td > < td class = "benchmarkresult" > 151< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string copy{str_with_len_N};/1024< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 39.6< / td > < td class = "benchmarkresult" > 37.2< / td > < td class = "benchmarkresult" > 95.3< / td > < td class = "benchmarkresult" > 99.1< / td > < td class = "benchmarkresult" > 131< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string copy{str_with_len_N};/2048< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 81.3< / td > < td class = "benchmarkresult" > 81.5< / td > < td class = "benchmarkresult" > 127< / td > < td class = "benchmarkresult" > 140< / td > < td class = "benchmarkresult" > 148< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string copy{str_with_len_N};/4096< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Чем длиннее строка, тем дольше создаётся копия.< / span > < / span > < / td > < td class = "benchmarkresult" > 117< / td > < td class = "benchmarkresult" > 118< / td > < td class = "benchmarkresult" > 176< / td > < td class = "benchmarkresult" > 187< / td > < td class = "benchmarkresult" > 185< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa copy{str_with_len_N};/15< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Здесь stringa инициализируется не литералом,
2025-11-26 19:15:50 +00:00
а значит, должна сама хранить символы.< / span > < / span > < / td > < td class = "benchmarkresult" > 1.13< / td > < td class = "benchmarkresult" > 1.13< / td > < td class = "benchmarkresult" > 1.34< / td > < td class = "benchmarkresult" > 4.03< / td > < td class = "benchmarkresult" > 5.19< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa copy{str_with_len_N};/16< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Под WASM SSO у stringa составляет 15 символов. Кроме того,
собиралось без поддержки потоков, поэтому возможно атомарный
2025-11-26 19:15:50 +00:00
инкремент заменён на обычный, судя по времени.< / span > < / span > < / td > < td class = "benchmarkresult" > 1.12< / td > < td class = "benchmarkresult" > 1.14< / td > < td class = "benchmarkresult" > 1.35< / td > < td class = "benchmarkresult" > 4.09< / td > < td class = "benchmarkresult" > 10.0< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa copy{str_with_len_N};/23< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > SSO в stringa до 23 символов, и даже 23
2025-11-26 19:15:50 +00:00
копируются быстрее, чем 15 в std::string.< / span > < / span > < / td > < td class = "benchmarkresult" > 1.11< / td > < td class = "benchmarkresult" > 1.20< / td > < td class = "benchmarkresult" > 1.35< / td > < td class = "benchmarkresult" > 4.06< / td > < td class = "benchmarkresult" > 9.97< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa copy{str_with_len_N};/24< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Всё, не влезаем в SSO, а значит, используем shared буфер.
2025-11-26 19:15:50 +00:00
Добавляется время на атомарный инкремент счётчика.< / span > < / span > < / td > < td class = "benchmarkresult" > 16.6< / td > < td class = "benchmarkresult" > 16.3< / td > < td class = "benchmarkresult" > 15.8< / td > < td class = "benchmarkresult" > 18.7< / td > < td class = "benchmarkresult" > 10.1< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa copy{str_with_len_N};/32< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 16.2< / td > < td class = "benchmarkresult" > 16.2< / td > < td class = "benchmarkresult" > 15.8< / td > < td class = "benchmarkresult" > 18.6< / td > < td class = "benchmarkresult" > 10.0< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa copy{str_with_len_N};/64< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 16.0< / td > < td class = "benchmarkresult" > 16.2< / td > < td class = "benchmarkresult" > 16.0< / td > < td class = "benchmarkresult" > 18.9< / td > < td class = "benchmarkresult" > 9.95< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa copy{str_with_len_N};/128< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 16.2< / td > < td class = "benchmarkresult" > 16.3< / td > < td class = "benchmarkresult" > 15.8< / td > < td class = "benchmarkresult" > 18.4< / td > < td class = "benchmarkresult" > 9.93< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa copy{str_with_len_N};/256< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 16.0< / td > < td class = "benchmarkresult" > 16.2< / td > < td class = "benchmarkresult" > 15.8< / td > < td class = "benchmarkresult" > 18.6< / td > < td class = "benchmarkresult" > 9.95< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa copy{str_with_len_N};/512< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 16.0< / td > < td class = "benchmarkresult" > 16.1< / td > < td class = "benchmarkresult" > 16.0< / td > < td class = "benchmarkresult" > 19.5< / td > < td class = "benchmarkresult" > 10.0< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa copy{str_with_len_N};/1024< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 16.4< / td > < td class = "benchmarkresult" > 16.5< / td > < td class = "benchmarkresult" > 15.9< / td > < td class = "benchmarkresult" > 18.3< / td > < td class = "benchmarkresult" > 9.92< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa copy{str_with_len_N};/2048< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 16.1< / td > < td class = "benchmarkresult" > 16.3< / td > < td class = "benchmarkresult" > 16.0< / td > < td class = "benchmarkresult" > 18.5< / td > < td class = "benchmarkresult" > 10.0< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa copy{str_with_len_N};/4096< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > И как видно, кроме инкремента нет накладных расходов,
2025-11-26 19:15:50 +00:00
время копирования не зависит от длины строки.< / span > < / span > < / td > < td class = "benchmarkresult" > 16.1< / td > < td class = "benchmarkresult" > 16.2< / td > < td class = "benchmarkresult" > 15.9< / td > < td class = "benchmarkresult" > 18.9< / td > < td class = "benchmarkresult" > 10.1< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> copy{str_with_len_N};/15< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > lstringa< 16 > использует SSO до 23 символов.
2025-11-26 19:15:50 +00:00
А в WASM 32-битная архитектура, SSO до 19 символов.< / span > < / span > < / td > < td class = "benchmarkresult" > 5.08< / td > < td class = "benchmarkresult" > 4.88< / td > < td class = "benchmarkresult" > 4.96< / td > < td class = "benchmarkresult" > 7.85< / td > < td class = "benchmarkresult" > 17.2< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> copy{str_with_len_N};/16< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 4.97< / td > < td class = "benchmarkresult" > 4.89< / td > < td class = "benchmarkresult" > 4.87< / td > < td class = "benchmarkresult" > 8.07< / td > < td class = "benchmarkresult" > 17.0< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> copy{str_with_len_N};/23< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 4.90< / td > < td class = "benchmarkresult" > 5.01< / td > < td class = "benchmarkresult" > 4.98< / td > < td class = "benchmarkresult" > 7.94< / td > < td class = "benchmarkresult" > 77.8< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> copy{str_with_len_N};/24< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > И после начинает вести себя при копировании, как std::string.< / span > < / span > < / td > < td class = "benchmarkresult" > 24.2< / td > < td class = "benchmarkresult" > 25.0< / td > < td class = "benchmarkresult" > 84.0< / td > < td class = "benchmarkresult" > 82.8< / td > < td class = "benchmarkresult" > 76.5< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> copy{str_with_len_N};/32< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 24.1< / td > < td class = "benchmarkresult" > 24.5< / td > < td class = "benchmarkresult" > 88.0< / td > < td class = "benchmarkresult" > 85.5< / td > < td class = "benchmarkresult" > 79.5< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> copy{str_with_len_N};/64< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 25.6< / td > < td class = "benchmarkresult" > 25.9< / td > < td class = "benchmarkresult" > 84.8< / td > < td class = "benchmarkresult" > 85.1< / td > < td class = "benchmarkresult" > 82.9< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> copy{str_with_len_N};/128< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 27.3< / td > < td class = "benchmarkresult" > 26.5< / td > < td class = "benchmarkresult" > 85.1< / td > < td class = "benchmarkresult" > 89.8< / td > < td class = "benchmarkresult" > 83.0< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> copy{str_with_len_N};/256< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 27.6< / td > < td class = "benchmarkresult" > 29.6< / td > < td class = "benchmarkresult" > 88.2< / td > < td class = "benchmarkresult" > 655< / td > < td class = "benchmarkresult" > 133< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> copy{str_with_len_N};/512< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 30.4< / td > < td class = "benchmarkresult" > 30.9< / td > < td class = "benchmarkresult" > 89.4< / td > < td class = "benchmarkresult" > 92.5< / td > < td class = "benchmarkresult" > 130< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> copy{str_with_len_N};/1024< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 70.0< / td > < td class = "benchmarkresult" > 71.7< / td > < td class = "benchmarkresult" > 101< / td > < td class = "benchmarkresult" > 101< / td > < td class = "benchmarkresult" > 111< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> copy{str_with_len_N};/2048< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 74.5< / td > < td class = "benchmarkresult" > 74.3< / td > < td class = "benchmarkresult" > 131< / td > < td class = "benchmarkresult" > 132< / td > < td class = "benchmarkresult" > 122< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> copy{str_with_len_N};/4096< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 90.9< / td > < td class = "benchmarkresult" > 93.3< / td > < td class = "benchmarkresult" > 194< / td > < td class = "benchmarkresult" > 196< / td > < td class = "benchmarkresult" > 167< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> copy{str_with_len_N};/15< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 5.14< / td > < td class = "benchmarkresult" > 4.93< / td > < td class = "benchmarkresult" > 4.94< / td > < td class = "benchmarkresult" > 8.62< / td > < td class = "benchmarkresult" > 17.9< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> copy{str_with_len_N};/16< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 4.86< / td > < td class = "benchmarkresult" > 4.97< / td > < td class = "benchmarkresult" > 5.36< / td > < td class = "benchmarkresult" > 8.94< / td > < td class = "benchmarkresult" > 18.5< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> copy{str_with_len_N};/23< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 4.91< / td > < td class = "benchmarkresult" > 4.94< / td > < td class = "benchmarkresult" > 5.05< / td > < td class = "benchmarkresult" > 8.67< / td > < td class = "benchmarkresult" > 18.6< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> copy{str_with_len_N};/24< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 4.99< / td > < td class = "benchmarkresult" > 4.90< / td > < td class = "benchmarkresult" > 4.83< / td > < td class = "benchmarkresult" > 8.44< / td > < td class = "benchmarkresult" > 18.8< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> copy{str_with_len_N};/32< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 4.58< / td > < td class = "benchmarkresult" > 5.03< / td > < td class = "benchmarkresult" > 7.94< / td > < td class = "benchmarkresult" > 12.0< / td > < td class = "benchmarkresult" > 25.0< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> copy{str_with_len_N};/64< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 6.06< / td > < td class = "benchmarkresult" > 6.12< / td > < td class = "benchmarkresult" > 7.92< / td > < td class = "benchmarkresult" > 12.1< / td > < td class = "benchmarkresult" > 21.2< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> copy{str_with_len_N};/128< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 6.44< / td > < td class = "benchmarkresult" > 7.87< / td > < td class = "benchmarkresult" > 8.26< / td > < td class = "benchmarkresult" > 12.3< / td > < td class = "benchmarkresult" > 22.3< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> copy{str_with_len_N};/256< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 8.00< / td > < td class = "benchmarkresult" > 8.70< / td > < td class = "benchmarkresult" > 9.31< / td > < td class = "benchmarkresult" > 13.2< / td > < td class = "benchmarkresult" > 24.0< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> copy{str_with_len_N};/512< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Даже 512 символов копируются быстрее, чем
2025-11-26 19:15:50 +00:00
одна аллокация или атомарный инкремент.< / span > < / span > < / td > < td class = "benchmarkresult" > 10.7< / td > < td class = "benchmarkresult" > 10.6< / td > < td class = "benchmarkresult" > 10.9< / td > < td class = "benchmarkresult" > 14.6< / td > < td class = "benchmarkresult" > 26.8< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> copy{str_with_len_N};/1024< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > А дальше уже как у всех< / span > < / span > < / td > < td class = "benchmarkresult" > 69.8< / td > < td class = "benchmarkresult" > 71.4< / td > < td class = "benchmarkresult" > 99.0< / td > < td class = "benchmarkresult" > 98.2< / td > < td class = "benchmarkresult" > 113< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> copy{str_with_len_N};/2048< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 73.4< / td > < td class = "benchmarkresult" > 77.5< / td > < td class = "benchmarkresult" > 131< / td > < td class = "benchmarkresult" > 131< / td > < td class = "benchmarkresult" > 129< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> copy{str_with_len_N};/4096< span class = "tooltiptext code" > template< typename T>
void CopyDynString(benchmark::State& state) {
T x(state.range(0), ' a' );
for (auto _: state) {
T copy{x};
benchmark::DoNotOptimize(copy);
benchmark::DoNotOptimize(x);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 90.8< / td > < td class = "benchmarkresult" > 93.4< / td > < td class = "benchmarkresult" > 191< / td > < td class = "benchmarkresult" > 195< / td > < td class = "benchmarkresult" > 169< / td > < / tr >
2025-04-05 14:21:11 +00:00
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' C o p y n o t l i t e r a l S t r w i t h N s y m b o l s ' ] = { i d : ' b s 7 ' , t e s t s : [
2025-11-26 19:15:50 +00:00
{name:'std::string copy{str_with_len_N};/15',data:[4.90,5.07,1.86,4.45,97.2]},
{name:'std::string copy{str_with_len_N};/16',data:[23.1,23.7,81.6,94.0,94.6]},
{name:'std::string copy{str_with_len_N};/23',data:[23.2,23.9,79.8,94.8,91.6]},
{name:'std::string copy{str_with_len_N};/24',data:[22.3,24.9,80.5,97.7,94.5]},
{name:'std::string copy{str_with_len_N};/32',data:[22.2,22.6,86.2,95.8,97.0]},
{name:'std::string copy{str_with_len_N};/64',data:[22.6,22.9,79.3,94.1,98.1]},
{name:'std::string copy{str_with_len_N};/128',data:[26.2,24.2,85.0,103,103]},
{name:'std::string copy{str_with_len_N};/256',data:[27.3,25.5,84.4,105,161]},
{name:'std::string copy{str_with_len_N};/512',data:[28.3,29.2,86.6,97.1,151]},
{name:'std::string copy{str_with_len_N};/1024',data:[39.6,37.2,95.3,99.1,131]},
{name:'std::string copy{str_with_len_N};/2048',data:[81.3,81.5,127,140,148]},
{name:'std::string copy{str_with_len_N};/4096',data:[117,118,176,187,185]},
{name:'stringa copy{str_with_len_N};/15',data:[1.13,1.13,1.34,4.03,5.19]},
{name:'stringa copy{str_with_len_N};/16',data:[1.12,1.14,1.35,4.09,10.0]},
{name:'stringa copy{str_with_len_N};/23',data:[1.11,1.20,1.35,4.06,9.97]},
{name:'stringa copy{str_with_len_N};/24',data:[16.6,16.3,15.8,18.7,10.1]},
{name:'stringa copy{str_with_len_N};/32',data:[16.2,16.2,15.8,18.6,10.0]},
{name:'stringa copy{str_with_len_N};/64',data:[16.0,16.2,16.0,18.9,9.95]},
{name:'stringa copy{str_with_len_N};/128',data:[16.2,16.3,15.8,18.4,9.93]},
{name:'stringa copy{str_with_len_N};/256',data:[16.0,16.2,15.8,18.6,9.95]},
{name:'stringa copy{str_with_len_N};/512',data:[16.0,16.1,16.0,19.5,10.0]},
{name:'stringa copy{str_with_len_N};/1024',data:[16.4,16.5,15.9,18.3,9.92]},
{name:'stringa copy{str_with_len_N};/2048',data:[16.1,16.3,16.0,18.5,10.0]},
{name:'stringa copy{str_with_len_N};/4096',data:[16.1,16.2,15.9,18.9,10.1]},
{name:'lstringa< 16 > copy{str_with_len_N};/15',data:[5.08,4.88,4.96,7.85,17.2]},
{name:'lstringa< 16 > copy{str_with_len_N};/16',data:[4.97,4.89,4.87,8.07,17.0]},
{name:'lstringa< 16 > copy{str_with_len_N};/23',data:[4.90,5.01,4.98,7.94,77.8]},
{name:'lstringa< 16 > copy{str_with_len_N};/24',data:[24.2,25.0,84.0,82.8,76.5]},
{name:'lstringa< 16 > copy{str_with_len_N};/32',data:[24.1,24.5,88.0,85.5,79.5]},
{name:'lstringa< 16 > copy{str_with_len_N};/64',data:[25.6,25.9,84.8,85.1,82.9]},
{name:'lstringa< 16 > copy{str_with_len_N};/128',data:[27.3,26.5,85.1,89.8,83.0]},
{name:'lstringa< 16 > copy{str_with_len_N};/256',data:[27.6,29.6,88.2,655,133]},
{name:'lstringa< 16 > copy{str_with_len_N};/512',data:[30.4,30.9,89.4,92.5,130]},
{name:'lstringa< 16 > copy{str_with_len_N};/1024',data:[70.0,71.7,101,101,111]},
{name:'lstringa< 16 > copy{str_with_len_N};/2048',data:[74.5,74.3,131,132,122]},
{name:'lstringa< 16 > copy{str_with_len_N};/4096',data:[90.9,93.3,194,196,167]},
{name:'lstringa< 512 > copy{str_with_len_N};/15',data:[5.14,4.93,4.94,8.62,17.9]},
{name:'lstringa< 512 > copy{str_with_len_N};/16',data:[4.86,4.97,5.36,8.94,18.5]},
{name:'lstringa< 512 > copy{str_with_len_N};/23',data:[4.91,4.94,5.05,8.67,18.6]},
{name:'lstringa< 512 > copy{str_with_len_N};/24',data:[4.99,4.90,4.83,8.44,18.8]},
{name:'lstringa< 512 > copy{str_with_len_N};/32',data:[4.58,5.03,7.94,12.0,25.0]},
{name:'lstringa< 512 > copy{str_with_len_N};/64',data:[6.06,6.12,7.92,12.1,21.2]},
{name:'lstringa< 512 > copy{str_with_len_N};/128',data:[6.44,7.87,8.26,12.3,22.3]},
{name:'lstringa< 512 > copy{str_with_len_N};/256',data:[8.00,8.70,9.31,13.2,24.0]},
{name:'lstringa< 512 > copy{str_with_len_N};/512',data:[10.7,10.6,10.9,14.6,26.8]},
{name:'lstringa< 512 > copy{str_with_len_N};/1024',data:[69.8,71.4,99.0,98.2,113]},
{name:'lstringa< 512 > copy{str_with_len_N};/2048',data:[73.4,77.5,131,131,129]},
{name:'lstringa< 512 > copy{str_with_len_N};/4096',data:[90.8,93.4,191,195,169]}
2025-04-05 14:21:11 +00:00
]}< / script >
< div class = "benchset" id = "bs8" > < h4 > Convert to int ' 1234567' < / h4 >
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string s = " 123456789" ; int res = std::strtol(s.c_str(), 0, 10);< span class = "tooltiptext code" > void ToIntStr10(benchmark::State& state, const std::string& s, int c) {
for (auto _: state) {
int res = std::strtol(s.c_str(), nullptr, 10);
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > В simstr для конвертации в число достаточно куска строки,
нет нужды в null терминированности. Ближайший аналог такого
поведения "std::from_chars", но он к сожалению очень ограничен
по возможностям. Здесь я попытался произвести тесты, близкие по
2025-11-26 19:15:50 +00:00
логике к работе std::from_chars< / span > < / span > < / td > < td class = "benchmarkresult" > 27.5< / td > < td class = "benchmarkresult" > 27.0< / td > < td class = "benchmarkresult" > 31.7< / td > < td class = "benchmarkresult" > 32.4< / td > < td class = "benchmarkresult" > 204< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string_view s = " 123456789" ; std::from_chars(s.data(), s.data() + s.size(), res, 10);< span class = "tooltiptext code" > void ToIntFromChars10(benchmark::State& state, const std::string_view& s, int c) {
for (auto _: state) {
int res = 0;
std::from_chars(s.data(), s.data() + s.size(), res, 10);
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > from_chars требует точного указания основания счисления,
2025-11-26 19:15:50 +00:00
не допускает знаков плюс, пробелов, префиксов 0x и т.п.< / span > < / span > < / td > < td class = "benchmarkresult" > 15.8< / td > < td class = "benchmarkresult" > 12.3< / td > < td class = "benchmarkresult" > 13.9< / td > < td class = "benchmarkresult" > 15.0< / td > < td class = "benchmarkresult" > 65.9< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa s = " 123456789" ; int res = s.to_int< int, true, 10, false>< span class = "tooltiptext code" > template< typename T>
void ToIntSimStr10(benchmark::State& state, T t, int c) {
for (auto _: state) {
2025-11-26 19:15:50 +00:00
int res = t. template to_int< int, true, 10, false, false>().value;
2025-04-05 14:21:11 +00:00
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Здесь для to_int заданы такие же ограничения - проверять переполнение,
2025-11-26 19:15:50 +00:00
десятичная система, без лидирующих пробелов и знака плюс< / span > < / span > < / td > < td class = "benchmarkresult" > 12.8< / td > < td class = "benchmarkresult" > 8.38< / td > < td class = "benchmarkresult" > 14.3< / td > < td class = "benchmarkresult" > 15.3< / td > < td class = "benchmarkresult" > 58.9< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > ssa s = " 123456789" ; int res = s.to_int< int, true, 10, false>< span class = "tooltiptext code" > template< typename T>
void ToIntSimStr10(benchmark::State& state, T t, int c) {
for (auto _: state) {
2025-11-26 19:15:50 +00:00
int res = t. template to_int< int, true, 10, false, false>().value;
2025-04-05 14:21:11 +00:00
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 12.5< / td > < td class = "benchmarkresult" > 8.48< / td > < td class = "benchmarkresult" > 13.0< / td > < td class = "benchmarkresult" > 16.2< / td > < td class = "benchmarkresult" > 54.2< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 20> s = " 123456789" ; int res = s.to_int< int, true, 10, false>< span class = "tooltiptext code" > template< typename T>
void ToIntSimStr10(benchmark::State& state, T t, int c) {
for (auto _: state) {
2025-11-26 19:15:50 +00:00
int res = t. template to_int< int, true, 10, false, false>().value;
2025-04-05 14:21:11 +00:00
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 12.5< / td > < td class = "benchmarkresult" > 8.36< / td > < td class = "benchmarkresult" > 13.4< / td > < td class = "benchmarkresult" > 15.9< / td > < td class = "benchmarkresult" > 54.1< / td > < / tr >
2025-04-05 14:21:11 +00:00
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' C o n v e r t t o i n t \ ' 1 2 3 4 5 6 7 \ ' ' ] = { i d : ' b s 8 ' , t e s t s : [
2025-11-26 19:15:50 +00:00
{name:'std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);',data:[27.5,27.0,31.7,32.4,204]},
{name:'std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);',data:[15.8,12.3,13.9,15.0,65.9]},
{name:'stringa s = "123456789"; int res = s.to_int< int , true , 10 , false > ',data:[12.8,8.38,14.3,15.3,58.9]},
{name:'ssa s = "123456789"; int res = s.to_int< int , true , 10 , false > ',data:[12.5,8.48,13.0,16.2,54.2]},
{name:'lstringa< 20 > s = "123456789"; int res = s.to_int< int , true , 10 , false > ',data:[12.5,8.36,13.4,15.9,54.1]}
2025-04-05 14:21:11 +00:00
]}< / script >
< div class = "benchset" id = "bs9" > < h4 > Convert to unsigned ' abcDef' < / h4 >
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string s = " abcDef" ; int res = std::strtol(s.c_str(), 0, 16);< span class = "tooltiptext code" > void ToIntStr16(benchmark::State& state, const std::string& s, int c) {
for (auto _: state) {
int res = std::strtol(s.c_str(), nullptr, 16);
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Всё то же, только для 16р ично й системы< / span > < / span > < / td > < td class = "benchmarkresult" > 23.9< / td > < td class = "benchmarkresult" > 24.3< / td > < td class = "benchmarkresult" > 34.5< / td > < td class = "benchmarkresult" > 35.7< / td > < td class = "benchmarkresult" > 158< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string_view s = " abcDef" ; std::from_chars(s.data(), s.data() + s.size(), res, 16);< span class = "tooltiptext code" > void ToIntFromChars16(benchmark::State& state, const std::string_view& s, int c) {
for (auto _: state) {
int res = 0;
std::from_chars(s.data(), s.data() + s.size(), res, 16);
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 10.0< / td > < td class = "benchmarkresult" > 15.0< / td > < td class = "benchmarkresult" > 8.49< / td > < td class = "benchmarkresult" > 9.90< / td > < td class = "benchmarkresult" > 85.4< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa s = " abcDef" ; int res = s.to_int< int, true, 16, false>< span class = "tooltiptext code" > template< typename T>
void ToIntSimStr16(benchmark::State& state, T t, int c) {
for (auto _: state) {
2025-11-26 19:15:50 +00:00
int res = t. template to_int< int, true, 16, false, false>().value;
2025-04-05 14:21:11 +00:00
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 12.9< / td > < td class = "benchmarkresult" > 8.57< / td > < td class = "benchmarkresult" > 12.3< / td > < td class = "benchmarkresult" > 14.6< / td > < td class = "benchmarkresult" > 50.4< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > ssa s = " abcDef" ; int res = s.to_int< int, true, 16, false>< span class = "tooltiptext code" > template< typename T>
void ToIntSimStr16(benchmark::State& state, T t, int c) {
for (auto _: state) {
2025-11-26 19:15:50 +00:00
int res = t. template to_int< int, true, 16, false, false>().value;
2025-04-05 14:21:11 +00:00
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 12.5< / td > < td class = "benchmarkresult" > 7.90< / td > < td class = "benchmarkresult" > 12.0< / td > < td class = "benchmarkresult" > 14.0< / td > < td class = "benchmarkresult" > 47.5< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 20> s = " abcDef" ; int res = s.to_int< int, true, 16, false>< span class = "tooltiptext code" > template< typename T>
void ToIntSimStr16(benchmark::State& state, T t, int c) {
for (auto _: state) {
2025-11-26 19:15:50 +00:00
int res = t. template to_int< int, true, 16, false, false>().value;
2025-04-05 14:21:11 +00:00
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 12.7< / td > < td class = "benchmarkresult" > 7.94< / td > < td class = "benchmarkresult" > 11.8< / td > < td class = "benchmarkresult" > 13.9< / td > < td class = "benchmarkresult" > 47.2< / td > < / tr >
2025-04-05 14:21:11 +00:00
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' C o n v e r t t o u n s i g n e d \ ' a b c D e f \ ' ' ] = { i d : ' b s 9 ' , t e s t s : [
2025-11-26 19:15:50 +00:00
{name:'std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);',data:[23.9,24.3,34.5,35.7,158]},
{name:'std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);',data:[10.0,15.0,8.49,9.90,85.4]},
{name:'stringa s = "abcDef"; int res = s.to_int< int , true , 16 , false > ',data:[12.9,8.57,12.3,14.6,50.4]},
{name:'ssa s = "abcDef"; int res = s.to_int< int , true , 16 , false > ',data:[12.5,7.90,12.0,14.0,47.5]},
{name:'lstringa< 20 > s = "abcDef"; int res = s.to_int< int , true , 16 , false > ',data:[12.7,7.94,11.8,13.9,47.2]}
2025-04-05 14:21:11 +00:00
]}< / script >
< div class = "benchset" id = "bs10" > < h4 > Convert to int ' 1234567' < / h4 >
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string s = " 123456789" ; int res = std::strtol(s.c_str(), 0, 0);< span class = "tooltiptext code" > void ToIntStr0(benchmark::State& state, const std::string& s, int c) {
for (auto _: state) {
int res = std::strtol(s.c_str(), nullptr, 0);
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > А здесь уже парсинг произвольного числа.< / span > < / span > < / td > < td class = "benchmarkresult" > 28.9< / td > < td class = "benchmarkresult" > 28.7< / td > < td class = "benchmarkresult" > 44.1< / td > < td class = "benchmarkresult" > 47.2< / td > < td class = "benchmarkresult" > 226< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa s = " 123456789" ; int res = s.to_int< int>; // Check overflow< span class = "tooltiptext code" > template< typename T>
void ToIntSimStr0(benchmark::State& state, T t, int c) {
for (auto _: state) {
2025-11-26 19:15:50 +00:00
int res = t. template to_int< int>().value;
2025-04-05 14:21:11 +00:00
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 18.8< / td > < td class = "benchmarkresult" > 15.7< / td > < td class = "benchmarkresult" > 17.2< / td > < td class = "benchmarkresult" > 20.0< / td > < td class = "benchmarkresult" > 80.3< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > ssa s = " 123456789" ; int res = s.to_int< int, false>; // No check overflow< span class = "tooltiptext code" > void ToIntNoOverflow(benchmark::State& state, ssa t, int c) {
for (auto _: state) {
2025-11-26 19:15:50 +00:00
int res = t.to_int< int, false>().value;
2025-04-05 14:21:11 +00:00
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 16.1< / td > < td class = "benchmarkresult" > 10.9< / td > < td class = "benchmarkresult" > 16.6< / td > < td class = "benchmarkresult" > 18.5< / td > < td class = "benchmarkresult" > 53.0< / td > < / tr >
2025-04-05 14:21:11 +00:00
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' C o n v e r t t o i n t \ ' 1 2 3 4 5 6 7 \ ' ' ] = { i d : ' b s 1 0 ' , t e s t s : [
2025-11-26 19:15:50 +00:00
{name:'std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);',data:[28.9,28.7,44.1,47.2,226]},
{name:'stringa s = " 123456789"; int res = s.to_int< int > ; // Check overflow',data:[18.8,15.7,17.2,20.0,80.3]},
{name:'ssa s = " 123456789"; int res = s.to_int< int , false > ; // No check overflow',data:[16.1,10.9,16.6,18.5,53.0]}
]}< / script >
< div class = "benchset" id = "bs11" > < h4 > Convert to double ' 1234.567e10' < / h4 >
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string s = " 1234.567e10" ; double res = std::strtod(s.c_str(), nullptr);< span class = "tooltiptext code" > void ToDoubleStr(benchmark::State& state, const std::string& s, double c) {
for (auto _: state) {
char* ptr = nullptr;
double res = std::strtod(s.c_str(), & ptr);
if (ptr == s.c_str()) {
state.SkipWithError(" not equal" );
}
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
}
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 65.0< / td > < td class = "benchmarkresult" > 65.0< / td > < td class = "benchmarkresult" > 103< / td > < td class = "benchmarkresult" > 106< / td > < td class = "benchmarkresult" > 460< / td > < / tr >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string_view s = " 1234.567e10" ; std::from_chars(s.data(), s.data() + s.size(), res);< span class = "tooltiptext code" > void ToDoubleFromChars(benchmark::State& state, const std::string_view& s, double c) {
for (auto _: state) {
double res = 0;
if (std::from_chars(s.data(), s.data() + s.size(), res).ec != std::errc{}) {
state.SkipWithError(" not equal" );
}
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
}
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 24.2< / td > < td class = "benchmarkresult" > 23.9< / td > < td class = "benchmarkresult" > 62.8< / td > < td class = "benchmarkresult" > 85.6< / td > < td class = "benchmarkresult" > 294< / td > < / tr >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > ssa s = " 1234.567e10" ; double res = *s.to_double()< span class = "tooltiptext code" > template< typename T>
void ToDoubleSimStr(benchmark::State& state, T t, double c) {
for (auto _: state) {
auto r = t.template to_double< false>();
if (!r) {
state.SkipWithError(" not equal" );
}
double res = *r;
#ifdef CHECK_RESULT
if (res != c) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(res);
benchmark::DoNotOptimize(t);
}
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 26.1< / td > < td class = "benchmarkresult" > 24.3< / td > < td class = "benchmarkresult" > 35.7< / td > < td class = "benchmarkresult" > 37.7< / td > < td class = "benchmarkresult" > 105< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' C o n v e r t t o d o u b l e \ ' 1 2 3 4 . 5 6 7 e 1 0 \ ' ' ] = { i d : ' b s 1 1 ' , t e s t s : [
{name:'std::string s = "1234.567e10"; double res = std::strtod(s.c_str(), nullptr);',data:[65.0,65.0,103,106,460]},
{name:'std::string_view s = "1234.567e10"; std::from_chars(s.data(), s.data() + s.size(), res);',data:[24.2,23.9,62.8,85.6,294]},
{name:'ssa s = "1234.567e10"; double res = *s.to_double()',data:[26.1,24.3,35.7,37.7,105]}
2025-04-05 14:21:11 +00:00
]}< / script >
2025-11-26 19:15:50 +00:00
< div class = "benchset" id = "bs12" > < h4 > Append const literal of 16 bytes 64 times, 1024 total length< / h4 >
2025-04-05 14:21:11 +00:00
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::stringstream str; ... str < < " abbaabbaabbaabba" ;< span class = "tooltiptext code" > void AppendStreamConstLiteral(benchmark::State& state) {
for (auto _: state) {
std::string result;
std::stringstream str;
for (size_t c = 0; c < 64; c++) {
str < < TEXT_16;
}
result = str.str();
#ifdef CHECK_RESULT
if (result.size() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(str);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1403< / td > < td class = "benchmarkresult" > 1513< / td > < td class = "benchmarkresult" > 4774< / td > < td class = "benchmarkresult" > 5830< / td > < td class = "benchmarkresult" > 11819< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string str; ... str += " abbaabbaabbaabba" ;< span class = "tooltiptext code" > void AppendStdStringConstLiteral(benchmark::State& state) {
for (auto _: state) {
std::string result;
for (size_t c = 0; c < 64; c++) {
result += TEXT_16;
}
#ifdef CHECK_RESULT
if (result.size() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 359< / td > < td class = "benchmarkresult" > 346< / td > < td class = "benchmarkresult" > 1084< / td > < td class = "benchmarkresult" > 1313< / td > < td class = "benchmarkresult" > 1174< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 8> str; ... str += " abbaabbaabbaabba" ;< span class = "tooltiptext code" > template< unsigned N>
void AppendLstringConstLiteral(benchmark::State& state) {
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 64; c++) {
result += TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 337< / td > < td class = "benchmarkresult" > 371< / td > < td class = "benchmarkresult" > 767< / td > < td class = "benchmarkresult" > 973< / td > < td class = "benchmarkresult" > 1294< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 128> str; ... str += " abbaabbaabbaabba" ;< span class = "tooltiptext code" > template< unsigned N>
void AppendLstringConstLiteral(benchmark::State& state) {
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 64; c++) {
result += TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Чем больше внутренний буфер, тем меньше раз требуется
2025-11-26 19:15:50 +00:00
аллокация, тем быстрее результат.< / span > < / span > < / td > < td class = "benchmarkresult" > 242< / td > < td class = "benchmarkresult" > 264< / td > < td class = "benchmarkresult" > 391< / td > < td class = "benchmarkresult" > 541< / td > < td class = "benchmarkresult" > 900< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> str; ... str += " abbaabbaabbaabba" ;< span class = "tooltiptext code" > template< unsigned N>
void AppendLstringConstLiteral(benchmark::State& state) {
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 64; c++) {
result += TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 227< / td > < td class = "benchmarkresult" > 239< / td > < td class = "benchmarkresult" > 246< / td > < td class = "benchmarkresult" > 365< / td > < td class = "benchmarkresult" > 637< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 1024> str; ... str += " abbaabbaabbaabba" ;< span class = "tooltiptext code" > template< unsigned N>
void AppendLstringConstLiteral(benchmark::State& state) {
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 64; c++) {
result += TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 138< / td > < td class = "benchmarkresult" > 141< / td > < td class = "benchmarkresult" > 154< / td > < td class = "benchmarkresult" > 254< / td > < td class = "benchmarkresult" > 501< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' A p p e n d c o n s t l i t e r a l o f 1 6 b y t e s 6 4 t i m e s , 1 0 2 4 t o t a l l e n g t h ' ] = { i d : ' b s 1 2 ' , t e s t s : [
{name:'std::stringstream str; ... str < < "abbaabbaabbaabba";',data:[1403,1513,4774,5830,11819]},
{name:'std::string str; ... str += "abbaabbaabbaabba";',data:[359,346,1084,1313,1174]},
{name:'lstringa< 8 > str; ... str += "abbaabbaabbaabba";',data:[337,371,767,973,1294]},
{name:'lstringa< 128 > str; ... str += "abbaabbaabbaabba";',data:[242,264,391,541,900]},
{name:'lstringa< 512 > str; ... str += "abbaabbaabbaabba";',data:[227,239,246,365,637]},
{name:'lstringa< 1024 > str; ... str += "abbaabbaabbaabba";',data:[138,141,154,254,501]}
2025-04-05 14:21:11 +00:00
]}< / script >
2025-11-26 19:15:50 +00:00
< div class = "benchset" id = "bs13" > < h4 > Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length< / h4 >
2025-04-05 14:21:11 +00:00
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::stringstream str; ... str < < str_var < < " abbaabbaabbaabba" ;< span class = "tooltiptext code" > void AppendStreamStrConstLiteral(benchmark::State& state) {
std::string s1 = TEXT_16;
for (auto _: state) {
std::string result;
std::stringstream s;
for (size_t c = 0; c < 32; c++) {
s < < s1 < < TEXT_16;
}
result = s.str();
#ifdef CHECK_RESULT
if (result.size() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1403< / td > < td class = "benchmarkresult" > 1456< / td > < td class = "benchmarkresult" > 4816< / td > < td class = "benchmarkresult" > 5571< / td > < td class = "benchmarkresult" > 11807< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string str; ... str += str_var + " abbaabbaabbaabba" ;< span class = "tooltiptext code" > void AppendStdStrStrConstLiteral(benchmark::State& state) {
std::string p1 = TEXT_16;
for (auto _: state) {
std::string result;
for (size_t c = 0; c < 32; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.size() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1296< / td > < td class = "benchmarkresult" > 1276< / td > < td class = "benchmarkresult" > 3968< / td > < td class = "benchmarkresult" > 4182< / td > < td class = "benchmarkresult" > 4085< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 8> str; ... str += str_var + " abbaabbaabbaabba" ;< span class = "tooltiptext code" > template< unsigned N>
void AppendLstringStrConstLiteral(benchmark::State& state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 32; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 431< / td > < td class = "benchmarkresult" > 420< / td > < td class = "benchmarkresult" > 796< / td > < td class = "benchmarkresult" > 827< / td > < td class = "benchmarkresult" > 1439< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 128> str; ... str += str_var + " abbaabbaabbaabba" ;< span class = "tooltiptext code" > template< unsigned N>
void AppendLstringStrConstLiteral(benchmark::State& state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 32; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 326< / td > < td class = "benchmarkresult" > 355< / td > < td class = "benchmarkresult" > 492< / td > < td class = "benchmarkresult" > 542< / td > < td class = "benchmarkresult" > 1179< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> str; ... str += str_var + " abbaabbaabbaabba" ;< span class = "tooltiptext code" > template< unsigned N>
void AppendLstringStrConstLiteral(benchmark::State& state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 32; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 312< / td > < td class = "benchmarkresult" > 310< / td > < td class = "benchmarkresult" > 315< / td > < td class = "benchmarkresult" > 381< / td > < td class = "benchmarkresult" > 934< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 1024> str; ... str += str_var + " abbaabbaabbaabba" ;< span class = "tooltiptext code" > template< unsigned N>
void AppendLstringStrConstLiteral(benchmark::State& state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 32; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 253< / td > < td class = "benchmarkresult" > 253< / td > < td class = "benchmarkresult" > 216< / td > < td class = "benchmarkresult" > 271< / td > < td class = "benchmarkresult" > 734< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' A p p e n d s t r i n g o f 1 6 b y t e s a n d c o n s t l i t e r a l o f 1 6 b y t e s 3 2 t i m e s , 1 0 2 4 t o t a l l e n g t h ' ] = { i d : ' b s 1 3 ' , t e s t s : [
{name:'std::stringstream str; ... str < < str_var < < " abbaabbaabbaabba " ; ' , data: [ 1403 , 1456 , 4816 , 5571 , 11807 ] } ,
{name:'std::string str; ... str += str_var + "abbaabbaabbaabba";',data:[1296,1276,3968,4182,4085]},
{name:'lstringa< 8 > str; ... str += str_var + "abbaabbaabbaabba";',data:[431,420,796,827,1439]},
{name:'lstringa< 128 > str; ... str += str_var + "abbaabbaabbaabba";',data:[326,355,492,542,1179]},
{name:'lstringa< 512 > str; ... str += str_var + "abbaabbaabbaabba";',data:[312,310,315,381,934]},
{name:'lstringa< 1024 > str; ... str += str_var + "abbaabbaabbaabba";',data:[253,253,216,271,734]}
2025-04-05 14:21:11 +00:00
]}< / script >
2025-11-26 19:15:50 +00:00
< div class = "benchset" id = "bs14" > < h4 > Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length< / h4 >
2025-04-05 14:21:11 +00:00
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::stringstream str; ... str < < str_var < < " abbaabbaabbaabba" ; 2048 times< span class = "tooltiptext code" > void AppendStreamStrConstLiteralBig(benchmark::State& state) {
std::string s1 = TEXT_16;
for (auto _: state) {
std::string result;
std::stringstream s;
for (size_t c = 0; c < 2048; c++) {
s < < s1 < < TEXT_16;
}
result = s.str();
#ifdef CHECK_RESULT
if (result.size() != 1024 * 64) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 125727< / td > < td class = "benchmarkresult" > 132670< / td > < td class = "benchmarkresult" > 219773< / td > < td class = "benchmarkresult" > 284627< / td > < td class = "benchmarkresult" > 609176< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string str; ... str += str_var + " abbaabbaabbaabba" ; 2048 times< span class = "tooltiptext code" > void AppendStdStrStrConstLiteralBig(benchmark::State& state) {
std::string p1 = TEXT_16;
for (auto _: state) {
std::string result;
for (size_t c = 0; c < 2048; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.size() != 1024 * 64) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 77160< / td > < td class = "benchmarkresult" > 74369< / td > < td class = "benchmarkresult" > 193770< / td > < td class = "benchmarkresult" > 193928< / td > < td class = "benchmarkresult" > 207760< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 8> str; ... str += str_var + " abbaabbaabbaabba" ; 2048 times< span class = "tooltiptext code" > template< unsigned N>
void AppendLstringStrConstLiteralBig(benchmark::State& state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 2048; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024 * 64) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 52479< / td > < td class = "benchmarkresult" > 55191< / td > < td class = "benchmarkresult" > 19446< / td > < td class = "benchmarkresult" > 23525< / td > < td class = "benchmarkresult" > 53812< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 128> str; ... str += str_var + " abbaabbaabbaabba" ; 2048 times< span class = "tooltiptext code" > template< unsigned N>
void AppendLstringStrConstLiteralBig(benchmark::State& state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 2048; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024 * 64) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 28389< / td > < td class = "benchmarkresult" > 28835< / td > < td class = "benchmarkresult" > 19410< / td > < td class = "benchmarkresult" > 22444< / td > < td class = "benchmarkresult" > 51889< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> str; ... str += str_var + " abbaabbaabbaabba" ; 2048 times< span class = "tooltiptext code" > template< unsigned N>
void AppendLstringStrConstLiteralBig(benchmark::State& state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 2048; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024 * 64) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 18137< / td > < td class = "benchmarkresult" > 19500< / td > < td class = "benchmarkresult" > 18772< / td > < td class = "benchmarkresult" > 22848< / td > < td class = "benchmarkresult" > 50113< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 1024> str; ... str += str_var + " abbaabbaabbaabba" ; 2048 times< span class = "tooltiptext code" > template< unsigned N>
void AppendLstringStrConstLiteralBig(benchmark::State& state) {
stringa p1 = TEXT_16;
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 2048; c++) {
result += p1 + TEXT_16;
}
#ifdef CHECK_RESULT
if (result.length() != 1024 * 64) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(p1);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 15503< / td > < td class = "benchmarkresult" > 18108< / td > < td class = "benchmarkresult" > 18557< / td > < td class = "benchmarkresult" > 21680< / td > < td class = "benchmarkresult" > 52780< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' A p p e n d s t r i n g o f 1 6 b y t e s a n d c o n s t l i t e r a l o f 1 6 b y t e s 2 0 4 8 t i m e s , 6 5 5 3 6 t o t a l l e n g t h ' ] = { i d : ' b s 1 4 ' , t e s t s : [
{name:'std::stringstream str; ... str < < str_var < < " abbaabbaabbaabba " ; 2048 times ' , data: [ 125727 , 132670 , 219773 , 284627 , 609176 ] } ,
{name:'std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[77160,74369,193770,193928,207760]},
{name:'lstringa< 8 > str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[52479,55191,19446,23525,53812]},
{name:'lstringa< 128 > str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[28389,28835,19410,22444,51889]},
{name:'lstringa< 512 > str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[18137,19500,18772,22848,50113]},
{name:'lstringa< 1024 > str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[15503,18108,18557,21680,52780]}
2025-04-05 14:21:11 +00:00
]}< / script >
2025-11-26 19:15:50 +00:00
< div class = "benchset" id = "bs15" > < h4 > Append 2 string of 16 bytes 32 times, 1024 total length< / h4 >
2025-04-05 14:21:11 +00:00
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::stringstream str; ... str < < str_var1 < < str_var2;< span class = "tooltiptext code" > void AppendStream2String(benchmark::State& state) {
std::string s1 = TEXT_16;
std::string s2 = TEXT_16;
for (auto _: state) {
std::string result;
std::stringstream s;
for (size_t c = 0; c < 32; c++) {
s < < s1 < < s2;
}
result = s.str();
#ifdef CHECK_RESULT
if (result.size() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
benchmark::DoNotOptimize(s2);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1369< / td > < td class = "benchmarkresult" > 1425< / td > < td class = "benchmarkresult" > 4503< / td > < td class = "benchmarkresult" > 5453< / td > < td class = "benchmarkresult" > 11836< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string str; ... str += str_var1 + str_var2;< span class = "tooltiptext code" > void AppendStdStr2String(benchmark::State& state) {
std::string s1 = TEXT_16;
std::string s2 = TEXT_16;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
for (auto _: state) {
std::string result;
for (size_t c = 0; c < 32; c++) {
result += s1 + s2;
}
#ifdef CHECK_RESULT
if (result.size() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
benchmark::DoNotOptimize(s2);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1396< / td > < td class = "benchmarkresult" > 1392< / td > < td class = "benchmarkresult" > 4062< / td > < td class = "benchmarkresult" > 4415< / td > < td class = "benchmarkresult" > 4507< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 16> str; ... str += str_var1 + str_var2;< span class = "tooltiptext code" > template< unsigned N>
void AppendLstring2String(benchmark::State& state) {
stra s1 = TEXT_16;
stra s2 = TEXT_16;
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 32; c++) {
result += s1 + s2;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
benchmark::DoNotOptimize(s2);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 523< / td > < td class = "benchmarkresult" > 630< / td > < td class = "benchmarkresult" > 842< / td > < td class = "benchmarkresult" > 959< / td > < td class = "benchmarkresult" > 1657< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 128> str; ... str += str_var1 + str_var2;< span class = "tooltiptext code" > template< unsigned N>
void AppendLstring2String(benchmark::State& state) {
stra s1 = TEXT_16;
stra s2 = TEXT_16;
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 32; c++) {
result += s1 + s2;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
benchmark::DoNotOptimize(s2);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 419< / td > < td class = "benchmarkresult" > 534< / td > < td class = "benchmarkresult" > 546< / td > < td class = "benchmarkresult" > 656< / td > < td class = "benchmarkresult" > 1413< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 512> str; ... str += str_var1 + str_var2;< span class = "tooltiptext code" > template< unsigned N>
void AppendLstring2String(benchmark::State& state) {
stra s1 = TEXT_16;
stra s2 = TEXT_16;
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 32; c++) {
result += s1 + s2;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
benchmark::DoNotOptimize(s2);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 395< / td > < td class = "benchmarkresult" > 470< / td > < td class = "benchmarkresult" > 416< / td > < td class = "benchmarkresult" > 484< / td > < td class = "benchmarkresult" > 1088< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 1024> str; ... str += str_var1 + str_var2;< span class = "tooltiptext code" > template< unsigned N>
void AppendLstring2String(benchmark::State& state) {
stra s1 = TEXT_16;
stra s2 = TEXT_16;
for (auto _: state) {
lstringa< N> result;
for (size_t c = 0; c < 32; c++) {
result += s1 + s2;
}
#ifdef CHECK_RESULT
if (result.length() != 1024) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(s1);
benchmark::DoNotOptimize(s2);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 311< / td > < td class = "benchmarkresult" > 434< / td > < td class = "benchmarkresult" > 311< / td > < td class = "benchmarkresult" > 388< / td > < td class = "benchmarkresult" > 977< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' A p p e n d 2 s t r i n g o f 1 6 b y t e s 3 2 t i m e s , 1 0 2 4 t o t a l l e n g t h ' ] = { i d : ' b s 1 5 ' , t e s t s : [
{name:'std::stringstream str; ... str < < str_var1 < < str_var2 ; ' , data: [ 1369 , 1425 , 4503 , 5453 , 11836 ] } ,
{name:'std::string str; ... str += str_var1 + str_var2;',data:[1396,1392,4062,4415,4507]},
{name:'lstringa< 16 > str; ... str += str_var1 + str_var2;',data:[523,630,842,959,1657]},
{name:'lstringa< 128 > str; ... str += str_var1 + str_var2;',data:[419,534,546,656,1413]},
{name:'lstringa< 512 > str; ... str += str_var1 + str_var2;',data:[395,470,416,484,1088]},
{name:'lstringa< 1024 > str; ... str += str_var1 + str_var2;',data:[311,434,311,388,977]}
2025-04-05 14:21:11 +00:00
]}< / script >
2025-11-26 19:15:50 +00:00
< div class = "benchset" id = "bs16" > < h4 > Append text, number, text< / h4 >
2025-04-05 14:21:11 +00:00
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::stringstream str; str < < " test = " < < k < < " times" ;< span class = "tooltiptext code" > void AppendStreamStrNumStr(benchmark::State& state) {
for (auto _: state) {
for (unsigned k = 1; k < = 1' 000' 000' 000; k *= 10) {
std::stringstream t;
t < < " test = " < < k < < " times" ;
std::string result = t.str();
#ifdef CHECK_RESULT
if (!result.starts_with(" test = " ) || !result.ends_with(" times" )) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 3149< / td > < td class = "benchmarkresult" > 3106< / td > < td class = "benchmarkresult" > 10976< / td > < td class = "benchmarkresult" > 12174< / td > < td class = "benchmarkresult" > 19450< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string str = " test = " + std::to_string(k) + " times" ;< span class = "tooltiptext code" > void AppendStdStringStrNumStr(benchmark::State& state) {
for (auto _: state) {
for (unsigned k = 1; k < = 1' 000' 000' 000; k *= 10) {
std::string result = " test = " + std::to_string(k) + " times" ;
#ifdef CHECK_RESULT
if (!result.starts_with(" test = " ) || !result.ends_with(" times" )) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 482< / td > < td class = "benchmarkresult" > 448< / td > < td class = "benchmarkresult" > 1131< / td > < td class = "benchmarkresult" > 1244< / td > < td class = "benchmarkresult" > 3261< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > char buf[100]; sprintf(buf, " test = %u times" , k); std::string str = buf;< span class = "tooltiptext code" > void AppendSprintfStrNumStr(benchmark::State& state) {
for (auto _: state) {
for (unsigned k = 1; k < = 1' 000' 000' 000; k *= 10) {
char buf[100];
std::sprintf(buf, " test = %u times" , k);
std::string result = buf;
#ifdef CHECK_RESULT
if (!result.starts_with(" test = " ) || !result.ends_with(" times" )) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1416< / td > < td class = "benchmarkresult" > 1526< / td > < td class = "benchmarkresult" > 2941< / td > < td class = "benchmarkresult" > 2886< / td > < td class = "benchmarkresult" > 7677< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string str = std::format(" test = {} times" , k);< span class = "tooltiptext code" > void AppendFormatStrNumStr(benchmark::State& state) {
for (auto _: state) {
for (unsigned k = 1; k < = 1' 000' 000' 000; k *= 10) {
std::string result = std::format(" test = {} times" , k);
#ifdef CHECK_RESULT
if (!result.starts_with(" test = " ) || !result.ends_with(" times" )) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1134< / td > < td class = "benchmarkresult" > 1271< / td > < td class = "benchmarkresult" > 2082< / td > < td class = "benchmarkresult" > 2480< / td > < td class = "benchmarkresult" > 4200< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 8> str; str.format(" test = {} times" , k);< span class = "tooltiptext code" > template< typename T>
void AppendSimStrStrNumStrF(benchmark::State& state) {
for (auto _: state) {
for (unsigned k = 1; k < = 1' 000' 000' 000; k *= 10) {
T result;
result.format(" test = {} times" , k);
#ifdef CHECK_RESULT
if (!result.starts_with(" test = " ) || !result.ends_with(" times" )) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > В simstr format с первого раза не помещается в такую строку без аллокации.< / span > < / span > < / td > < td class = "benchmarkresult" > 1390< / td > < td class = "benchmarkresult" > 1674< / td > < td class = "benchmarkresult" > 2137< / td > < td class = "benchmarkresult" > 2641< / td > < td class = "benchmarkresult" > 6598< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 32> str; str.format(" test = {} times" , k);< span class = "tooltiptext code" > template< typename T>
void AppendSimStrStrNumStrF(benchmark::State& state) {
for (auto _: state) {
for (unsigned k = 1; k < = 1' 000' 000' 000; k *= 10) {
T result;
result.format(" test = {} times" , k);
#ifdef CHECK_RESULT
if (!result.starts_with(" test = " ) || !result.ends_with(" times" )) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > А в такую помещается. Используйте сразу буфера подходящего размера.< / span > < / span > < / td > < td class = "benchmarkresult" > 963< / td > < td class = "benchmarkresult" > 1138< / td > < td class = "benchmarkresult" > 1004< / td > < td class = "benchmarkresult" > 1551< / td > < td class = "benchmarkresult" > 4632< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 8> str = " test = " + k + " times" ;< span class = "tooltiptext code" > template< typename T>
void AppendSimStrStrNumStr(benchmark::State& state) {
for (auto _: state) {
for (unsigned k = 1; k < = 1' 000' 000' 000; k *= 10) {
T result = " test = " _ss + k + " times" ;
#ifdef CHECK_RESULT
if (!result.starts_with(" test = " ) || !result.ends_with(" times" )) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Результат не помещается в SSO, возникает аллокация.< / span > < / span > < / td > < td class = "benchmarkresult" > 290< / td > < td class = "benchmarkresult" > 317< / td > < td class = "benchmarkresult" > 830< / td > < td class = "benchmarkresult" > 911< / td > < td class = "benchmarkresult" > 1342< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > lstringa< 32> str = " test = " + k + " times" ;< span class = "tooltiptext code" > template< typename T>
void AppendSimStrStrNumStr(benchmark::State& state) {
for (auto _: state) {
for (unsigned k = 1; k < = 1' 000' 000' 000; k *= 10) {
T result = " test = " _ss + k + " times" ;
#ifdef CHECK_RESULT
if (!result.starts_with(" test = " ) || !result.ends_with(" times" )) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > А здесь и ниже - результат укладывается в SSO.
2025-11-26 19:15:50 +00:00
Ещё раз - используйте сразу буфера подходящего размера.< / span > < / span > < / td > < td class = "benchmarkresult" > 157< / td > < td class = "benchmarkresult" > 154< / td > < td class = "benchmarkresult" > 158< / td > < td class = "benchmarkresult" > 195< / td > < td class = "benchmarkresult" > 614< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > stringa str = " test = " + k + " times" ;< span class = "tooltiptext code" > template< typename T>
void AppendSimStrStrNumStr(benchmark::State& state) {
for (auto _: state) {
for (unsigned k = 1; k < = 1' 000' 000' 000; k *= 10) {
T result = " test = " _ss + k + " times" ;
#ifdef CHECK_RESULT
if (!result.starts_with(" test = " ) || !result.ends_with(" times" )) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(k);
}
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Под WASM размер SSO 15 символов, что явно не хватает для размещения
2025-11-26 19:15:50 +00:00
результата, отсюда и такое время.< / span > < / span > < / td > < td class = "benchmarkresult" > 149< / td > < td class = "benchmarkresult" > 170< / td > < td class = "benchmarkresult" > 158< / td > < td class = "benchmarkresult" > 247< / td > < td class = "benchmarkresult" > 1303< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' A p p e n d t e x t , n u m b e r , t e x t ' ] = { i d : ' b s 1 6 ' , t e s t s : [
{name:'std::stringstream str; str < < "test = " < < k < < " times " ; ' , data: [ 3149 , 3106 , 10976 , 12174 , 19450 ] } ,
{name:'std::string str = "test = " + std::to_string(k) + " times";',data:[482,448,1131,1244,3261]},
{name:'char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;',data:[1416,1526,2941,2886,7677]},
{name:'std::string str = std::format("test = {} times", k);',data:[1134,1271,2082,2480,4200]},
{name:'lstringa< 8 > str; str.format("test = {} times", k);',data:[1390,1674,2137,2641,6598]},
{name:'lstringa< 32 > str; str.format("test = {} times", k);',data:[963,1138,1004,1551,4632]},
{name:'lstringa< 8 > str = "test = " + k + " times";',data:[290,317,830,911,1342]},
{name:'lstringa< 32 > str = "test = " + k + " times";',data:[157,154,158,195,614]},
{name:'stringa str = "test = " + k + " times";',data:[149,170,158,247,1303]}
2025-04-05 14:21:11 +00:00
]}< / script >
2025-11-26 19:15:50 +00:00
< div class = "benchset" id = "bs17" > < h4 > Split text and convert to int< / h4 >
2025-04-05 14:21:11 +00:00
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::string::find + substr + std::strtol< span class = "tooltiptext code" > void SplitConvertIntStdString(benchmark::State& state) {
std::string numbers = NUMBER_LIST;
for (auto _: state) {
int total = 0;
for (size_t start = 0; start < numbers.length(); ) {
int delim = numbers.find(" -!-" , start);
if (delim == std::string::npos) {
delim = numbers.size();
}
std::string part = numbers.substr(start, delim - start);
total += std::strtol(part.c_str(), nullptr, 0);
start = delim + 3;
}
#ifdef CHECK_RESULT
if (total != 218) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(total);
benchmark::DoNotOptimize(numbers);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 276< / td > < td class = "benchmarkresult" > 273< / td > < td class = "benchmarkresult" > 558< / td > < td class = "benchmarkresult" > 571< / td > < td class = "benchmarkresult" > 1414< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > ssa::splitter + ssa::as_int< span class = "tooltiptext code" > void SplitConvertIntSimStr(benchmark::State& state) {
stra numbers = NUMBER_LIST;
for (auto _: state) {
int total = 0;
for (auto splitter = numbers.splitter(" -!-" ); !splitter.is_done();) {
total += splitter.next().as_int< int>();
}
#ifdef CHECK_RESULT
if (total != 218) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(total);
benchmark::DoNotOptimize(numbers);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 154< / td > < td class = "benchmarkresult" > 137< / td > < td class = "benchmarkresult" > 171< / td > < td class = "benchmarkresult" > 311< / td > < td class = "benchmarkresult" > 670< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > ssa::splitf + functor< span class = "tooltiptext code" > void SplitConvertIntSplitf(benchmark::State& state) {
stra numbers = NUMBER_LIST;
for (auto _: state) {
int total = 0;
numbers.splitf< void>(" -!-" , [& ](ssa& part){total += part.as_int< int>();});
#ifdef CHECK_RESULT
if (total != 218) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(total);
benchmark::DoNotOptimize(numbers);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 214< / td > < td class = "benchmarkresult" > 130< / td > < td class = "benchmarkresult" > 190< / td > < td class = "benchmarkresult" > 220< / td > < td class = "benchmarkresult" > 939< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' S p l i t t e x t a n d c o n v e r t t o i n t ' ] = { i d : ' b s 1 7 ' , t e s t s : [
{name:'std::string::find + substr + std::strtol',data:[276,273,558,571,1414]},
{name:'ssa::splitter + ssa::as_int',data:[154,137,171,311,670]},
{name:'ssa::splitf + functor',data:[214,130,190,220,939]}
2025-04-05 14:21:11 +00:00
]}< / script >
2025-11-26 19:15:50 +00:00
< div class = "benchset" id = "bs18" > < h4 > Replace symbols in text ~400 symbols< / h4 >
2025-04-05 14:21:11 +00:00
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Naive (and wrong) replace symbols with std::string find + replace< span class = "tooltiptext code" > void ReplaceSymbolsStdStringNaiveWrong(benchmark::State& state) {
std::string_view source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
;
std::vector< std::pair< u8s, std::string_view>> repl = {
{' & ' , " & amp;" },
{' -' , " " },
{' < ' , " & lt;" },
{' >' , " & gt;" },
{' \' ' , " & #39;" },
{' \" ' , " & quot;" }
};
auto repl_all = [](std::string& str, char s, std::string_view repl) {
size_t start_pos = 0;
while((start_pos = str.find(s, start_pos)) != std::string::npos) {
str.replace(start_pos, 1, repl);
start_pos += repl.length();
}
};
for (auto _: state) {
std::string result{source};
for (const auto& r : repl) {
repl_all(result, r.first, r.second);
}
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Это наивная реализация, которая неверно отработает на
таких заменах, как 'a'->'b' и 'b'->'a'. Н о если замены не конфликтуют,
2025-11-26 19:15:50 +00:00
то работает быстро.< / span > < / span > < / td > < td class = "benchmarkresult" > 852< / td > < td class = "benchmarkresult" > 851< / td > < td class = "benchmarkresult" > 1171< / td > < td class = "benchmarkresult" > 1258< / td > < td class = "benchmarkresult" > 6175< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace symbols with std::string find_first_of + replace< span class = "tooltiptext code" > void ReplaceSymbolsStdStringNaiveRight(benchmark::State& state) {
std::string_view source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
;
std::vector< std::pair< u8s, std::string_view>> repl = {
{' -' , " " },
{' < ' , " & lt;" },
{' >' , " & gt;" },
{' \' ' , " & #39;" },
{' \" ' , " & quot;" },
{' & ' , " & amp;" },
};
for (auto _: state) {
std::string result{source};
std::string pattern;
for (const auto& r : repl) {
pattern += r.first;
}
size_t start_pos = 0;
while((start_pos = result.find_first_of(pattern, start_pos)) != std::string::npos) {
size_t idx = pattern.find(result[start_pos]);
result.replace(start_pos, 1, repl[idx].second);
start_pos += repl[idx].second.length();
}
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Дальше уже правильные реализации, не зависящие от конфликтующих замен.< / span > < / span > < / td > < td class = "benchmarkresult" > 2510< / td > < td class = "benchmarkresult" > 2496< / td > < td class = "benchmarkresult" > 2063< / td > < td class = "benchmarkresult" > 2344< / td > < td class = "benchmarkresult" > 10124< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace symbols with std::string_view find_first_of + copy< span class = "tooltiptext code" > void ReplaceSymbolsStdString(benchmark::State& state) {
std::string_view source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
const std::string_view repl_from = " -< >' \" & " ;
const std::string_view repl_to[] = {" " , " & lt;" , " & gt;" , " & #39;" , " & quot;" , " & amp;" };
for (auto _: state) {
std::string result;
for (size_t start = 0; start < source.size();) {
size_t idx = source.find_first_of(repl_from, start);
if (idx == std::string::npos) {
result += source.substr(start);
break;
}
if (idx > start) {
result += source.substr(start, idx - start);
}
size_t what = repl_from.find(source[idx]);
result += repl_to[what];
start = idx + 1;
}
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1110< / td > < td class = "benchmarkresult" > 973< / td > < td class = "benchmarkresult" > 2410< / td > < td class = "benchmarkresult" > 2606< / td > < td class = "benchmarkresult" > 5505< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace runtime symbols with string expressions and without remembering all search results< span class = "tooltiptext code" > template< bool UseVector>
void ReplaceSymbolsDynPatternSimStr(benchmark::State& state) {
stra source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
;
std::vector< std::pair< u8s, ssa>> repl = {
{' -' , " " },
{' < ' , " & lt;" },
{' >' , " & gt;" },
{' \' ' , " & #39;" },
{' \" ' , " & quot;" },
{' & ' , " & amp;" },
};
for (auto _: state) {
stringa result = expr_replace_symbols< u8s, UseVector>{source, repl};
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1235< / td > < td class = "benchmarkresult" > 1508< / td > < td class = "benchmarkresult" > 1441< / td > < td class = "benchmarkresult" > 1524< / td > < td class = "benchmarkresult" > 5599< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace runtime symbols with simstr and memorization of all search results< span class = "tooltiptext code" > template< bool UseVector>
void ReplaceSymbolsDynPatternSimStr(benchmark::State& state) {
stra source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
;
std::vector< std::pair< u8s, ssa>> repl = {
{' -' , " " },
{' < ' , " & lt;" },
{' >' , " & gt;" },
{' \' ' , " & #39;" },
{' \" ' , " & quot;" },
{' & ' , " & amp;" },
};
for (auto _: state) {
stringa result = expr_replace_symbols< u8s, UseVector>{source, repl};
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1069< / td > < td class = "benchmarkresult" > 1172< / td > < td class = "benchmarkresult" > 1396< / td > < td class = "benchmarkresult" > 1405< / td > < td class = "benchmarkresult" > 5123< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace const symbols with string expressions and without remembering all search results< span class = "tooltiptext code" > template< bool UseVector>
void ReplaceSymbolsCons2PatternSimStr(benchmark::State& state) {
stra source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
;
for (auto _: state) {
stringa result = e_repl_const_symbols< UseVector>(source,
' -' , " " ,
' < ' , " & lt;" ,
' >' , " & gt;" ,
' \' ' , " & #39;" ,
' \" ' , " & quot;" ,
' & ' , " & amp;"
);
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1084< / td > < td class = "benchmarkresult" > 1253< / td > < td class = "benchmarkresult" > 1209< / td > < td class = "benchmarkresult" > 1288< / td > < td class = "benchmarkresult" > 4773< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace const symbols with string expressions and memorization of all search results< span class = "tooltiptext code" > template< bool UseVector>
void ReplaceSymbolsCons2PatternSimStr(benchmark::State& state) {
stra source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
" ksjd-fksjd \" dkjfs-jkhdf dfj ' kdkd \" dkfdkfkdjf"
;
for (auto _: state) {
stringa result = e_repl_const_symbols< UseVector>(source,
' -' , " " ,
' < ' , " & lt;" ,
' >' , " & gt;" ,
' \' ' , " & #39;" ,
' \" ' , " & quot;" ,
' & ' , " & amp;"
);
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
" ksjdfksjd & quot;dkjfsjkhdf dfj & #39; kdkd & quot;dkfdkfkdjf"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 862< / td > < td class = "benchmarkresult" > 874< / td > < td class = "benchmarkresult" > 1206< / td > < td class = "benchmarkresult" > 1198< / td > < td class = "benchmarkresult" > 4477< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' R e p l a c e s y m b o l s i n t e x t ~ 4 0 0 s y m b o l s ' ] = { i d : ' b s 1 8 ' , t e s t s : [
{name:'Naive (and wrong) replace symbols with std::string find + replace',data:[852,851,1171,1258,6175]},
{name:'replace symbols with std::string find_first_of + replace',data:[2510,2496,2063,2344,10124]},
{name:'replace symbols with std::string_view find_first_of + copy',data:[1110,973,2410,2606,5505]},
{name:'replace runtime symbols with string expressions and without remembering all search results',data:[1235,1508,1441,1524,5599]},
{name:'replace runtime symbols with simstr and memorization of all search results',data:[1069,1172,1396,1405,5123]},
{name:'replace const symbols with string expressions and without remembering all search results',data:[1084,1253,1209,1288,4773]},
{name:'replace const symbols with string expressions and memorization of all search results',data:[862,874,1206,1198,4477]}
2025-04-05 14:21:11 +00:00
]}< / script >
2025-11-26 19:15:50 +00:00
< div class = "benchset" id = "bs19" > < h4 > Replace symbols in text ~40 symbols< / h4 >
2025-04-05 14:21:11 +00:00
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Short Naive (and wrong) replace symbols with std::string find + replace< span class = "tooltiptext code" > void ShortReplaceSymbolsStdStringNaiveWrong(benchmark::State& state) {
std::string_view source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
;
std::vector< std::pair< u8s, std::string_view>> repl = {
{' & ' , " & amp;" },
{' -' , " " },
{' < ' , " & lt;" },
{' >' , " & gt;" },
{' \' ' , " & #39;" },
{' \" ' , " & quot;" }
};
auto repl_all = [](std::string& str, char s, std::string_view repl) {
size_t start_pos = 0;
while((start_pos = str.find(s, start_pos)) != std::string::npos) {
str.replace(start_pos, 1, repl);
start_pos += repl.length();
}
};
for (auto _: state) {
std::string result{source};
for (const auto& r : repl) {
repl_all(result, r.first, r.second);
}
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 170< / td > < td class = "benchmarkresult" > 161< / td > < td class = "benchmarkresult" > 331< / td > < td class = "benchmarkresult" > 346< / td > < td class = "benchmarkresult" > 827< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Short replace symbols with std::string find_first_of + replace< span class = "tooltiptext code" > void ShortReplaceSymbolsStdStringNaiveRight(benchmark::State& state) {
std::string_view source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
;
std::vector< std::pair< u8s, std::string_view>> repl = {
{' -' , " " },
{' < ' , " & lt;" },
{' >' , " & gt;" },
{' \' ' , " & #39;" },
{' \" ' , " & quot;" },
{' & ' , " & amp;" },
};
for (auto _: state) {
std::string result{source};
std::string pattern;
for (const auto& r : repl) {
pattern += r.first;
}
size_t start_pos = 0;
while((start_pos = result.find_first_of(pattern, start_pos)) != std::string::npos) {
size_t idx = pattern.find(result[start_pos]);
result.replace(start_pos, 1, repl[idx].second);
start_pos += repl[idx].second.length();
}
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 310< / td > < td class = "benchmarkresult" > 321< / td > < td class = "benchmarkresult" > 375< / td > < td class = "benchmarkresult" > 435< / td > < td class = "benchmarkresult" > 1187< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Short replace symbols with std::string_view find_first_of + copy< span class = "tooltiptext code" > void ShortReplaceSymbolsStdString(benchmark::State& state) {
std::string_view source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
const std::string_view repl_from = " -< >' \" & " ;
const std::string_view repl_to[] = {" " , " & lt;" , " & gt;" , " & #39;" , " & quot;" , " & amp;" };
for (auto _: state) {
std::string result;
for (size_t start = 0; start < source.size();) {
size_t idx = source.find_first_of(repl_from, start);
if (idx == std::string::npos) {
result += source.substr(start);
break;
}
if (idx > start) {
result += source.substr(start, idx - start);
}
size_t what = repl_from.find_first_of(source[idx]);
result += repl_to[what];
start = idx + 1;
}
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 165< / td > < td class = "benchmarkresult" > 155< / td > < td class = "benchmarkresult" > 329< / td > < td class = "benchmarkresult" > 381< / td > < td class = "benchmarkresult" > 694< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Short replace runtime symbols with string expressions and without remembering all search results< span class = "tooltiptext code" > template< bool UseVector>
void ShortReplaceSymbolsDynPatternSimStr(benchmark::State& state) {
stra source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
;
std::vector< std::pair< u8s, ssa>> repl = {
{' -' , " " },
{' < ' , " & lt;" },
{' >' , " & gt;" },
{' \' ' , " & #39;" },
{' \" ' , " & quot;" },
{' & ' , " & amp;" },
};
for (auto _: state) {
stringa result = expr_replace_symbols< u8s, UseVector>{source, repl};
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 167< / td > < td class = "benchmarkresult" > 192< / td > < td class = "benchmarkresult" > 256< / td > < td class = "benchmarkresult" > 277< / td > < td class = "benchmarkresult" > 583< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Short replace runtime symbols with simstr and memorization of all search results< span class = "tooltiptext code" > template< bool UseVector>
void ShortReplaceSymbolsDynPatternSimStr(benchmark::State& state) {
stra source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
;
std::vector< std::pair< u8s, ssa>> repl = {
{' -' , " " },
{' < ' , " & lt;" },
{' >' , " & gt;" },
{' \' ' , " & #39;" },
{' \" ' , " & quot;" },
{' & ' , " & amp;" },
};
for (auto _: state) {
stringa result = expr_replace_symbols< u8s, UseVector>{source, repl};
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 176< / td > < td class = "benchmarkresult" > 190< / td > < td class = "benchmarkresult" > 369< / td > < td class = "benchmarkresult" > 374< / td > < td class = "benchmarkresult" > 669< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Short replace const symbols with string expressions and without remembering all search results< span class = "tooltiptext code" > template< bool UseVector>
void ShortReplaceSymbolsCons2PatternSimStr(benchmark::State& state) {
stra source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
;
for (auto _: state) {
stringa result = e_repl_const_symbols< UseVector>(source,
' -' , " " ,
' < ' , " & lt;" ,
' >' , " & gt;" ,
' \' ' , " & #39;" ,
' \" ' , " & quot;" ,
' & ' , " & amp;"
);
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 142< / td > < td class = "benchmarkresult" > 159< / td > < td class = "benchmarkresult" > 223< / td > < td class = "benchmarkresult" > 252< / td > < td class = "benchmarkresult" > 440< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Short replace const symbols with string expressions and memorization of all search results< span class = "tooltiptext code" > template< bool UseVector>
void ShortReplaceSymbolsCons2PatternSimStr(benchmark::State& state) {
stra source =
" abcdefg124 < jhsfjsh sjdfsh jfhjd & & jdjdj >"
;
for (auto _: state) {
stringa result = e_repl_const_symbols< UseVector>(source,
' -' , " " ,
' < ' , " & lt;" ,
' >' , " & gt;" ,
' \' ' , " & #39;" ,
' \" ' , " & quot;" ,
' & ' , " & amp;"
);
#ifdef CHECK_RESULT
if (result
!=
" abcdefg124 & lt; jhsfjsh sjdfsh jfhjd & amp;& amp; jdjdj & gt;"
) {
state.SkipWithError(" not equal" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 157< / td > < td class = "benchmarkresult" > 149< / td > < td class = "benchmarkresult" > 310< / td > < td class = "benchmarkresult" > 342< / td > < td class = "benchmarkresult" > 512< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' R e p l a c e s y m b o l s i n t e x t ~ 4 0 s y m b o l s ' ] = { i d : ' b s 1 9 ' , t e s t s : [
{name:'Short Naive (and wrong) replace symbols with std::string find + replace',data:[170,161,331,346,827]},
{name:'Short replace symbols with std::string find_first_of + replace',data:[310,321,375,435,1187]},
{name:'Short replace symbols with std::string_view find_first_of + copy',data:[165,155,329,381,694]},
{name:'Short replace runtime symbols with string expressions and without remembering all search results',data:[167,192,256,277,583]},
{name:'Short replace runtime symbols with simstr and memorization of all search results',data:[176,190,369,374,669]},
{name:'Short replace const symbols with string expressions and without remembering all search results',data:[142,159,223,252,440]},
{name:'Short replace const symbols with string expressions and memorization of all search results',data:[157,149,310,342,512]}
2025-04-05 14:21:11 +00:00
]}< / script >
2025-11-26 19:15:50 +00:00
< div class = "benchset" id = "bs20" > < h4 > Replace All Str To Longer Size< / h4 >
2025-04-05 14:21:11 +00:00
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- in std::string|64< span class = "tooltiptext code" > template< size_t Long>
void ReplaceAllLongerStdString(benchmark::State& state) {
std::string_view source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
std::string_view sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
std::string_view pattern = " bb" ;
std::string_view repl = " ----" ;
std::string big_source, big_sample;
for (int i = 0; i < Long; i++) {
big_source += source;
big_sample += sample;
}
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
for (auto _: state) {
std::string result{big_source};
size_t start_pos = 0;
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
result.replace(start_pos, pattern.length(), repl);
start_pos += repl.length();
}
#ifdef CHECK_RESULT
if (result != big_sample) {
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 164< / td > < td class = "benchmarkresult" > 174< / td > < td class = "benchmarkresult" > 236< / td > < td class = "benchmarkresult" > 248< / td > < td class = "benchmarkresult" > 759< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- in std::string|256< span class = "tooltiptext code" > template< size_t Long>
void ReplaceAllLongerStdString(benchmark::State& state) {
std::string_view source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
std::string_view sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
std::string_view pattern = " bb" ;
std::string_view repl = " ----" ;
std::string big_source, big_sample;
for (int i = 0; i < Long; i++) {
big_source += source;
big_sample += sample;
}
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
for (auto _: state) {
std::string result{big_source};
size_t start_pos = 0;
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
result.replace(start_pos, pattern.length(), repl);
start_pos += repl.length();
}
#ifdef CHECK_RESULT
if (result != big_sample) {
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 531< / td > < td class = "benchmarkresult" > 511< / td > < td class = "benchmarkresult" > 780< / td > < td class = "benchmarkresult" > 807< / td > < td class = "benchmarkresult" > 2371< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- in std::string|512< span class = "tooltiptext code" > template< size_t Long>
void ReplaceAllLongerStdString(benchmark::State& state) {
std::string_view source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
std::string_view sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
std::string_view pattern = " bb" ;
std::string_view repl = " ----" ;
std::string big_source, big_sample;
for (int i = 0; i < Long; i++) {
big_source += source;
big_sample += sample;
}
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
for (auto _: state) {
std::string result{big_source};
size_t start_pos = 0;
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
result.replace(start_pos, pattern.length(), repl);
start_pos += repl.length();
}
#ifdef CHECK_RESULT
if (result != big_sample) {
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1217< / td > < td class = "benchmarkresult" > 1180< / td > < td class = "benchmarkresult" > 1449< / td > < td class = "benchmarkresult" > 1551< / td > < td class = "benchmarkresult" > 4397< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- in std::string|1024< span class = "tooltiptext code" > template< size_t Long>
void ReplaceAllLongerStdString(benchmark::State& state) {
std::string_view source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
std::string_view sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
std::string_view pattern = " bb" ;
std::string_view repl = " ----" ;
std::string big_source, big_sample;
for (int i = 0; i < Long; i++) {
big_source += source;
big_sample += sample;
}
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
for (auto _: state) {
std::string result{big_source};
size_t start_pos = 0;
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
result.replace(start_pos, pattern.length(), repl);
start_pos += repl.length();
}
#ifdef CHECK_RESULT
if (result != big_sample) {
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 2374< / td > < td class = "benchmarkresult" > 2244< / td > < td class = "benchmarkresult" > 3239< / td > < td class = "benchmarkresult" > 3622< / td > < td class = "benchmarkresult" > 8983< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- in std::string|2048< span class = "tooltiptext code" > template< size_t Long>
void ReplaceAllLongerStdString(benchmark::State& state) {
std::string_view source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
std::string_view sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
std::string_view pattern = " bb" ;
std::string_view repl = " ----" ;
std::string big_source, big_sample;
for (int i = 0; i < Long; i++) {
big_source += source;
big_sample += sample;
}
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
for (auto _: state) {
std::string result{big_source};
size_t start_pos = 0;
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
result.replace(start_pos, pattern.length(), repl);
start_pos += repl.length();
}
#ifdef CHECK_RESULT
if (result != big_sample) {
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 5735< / td > < td class = "benchmarkresult" > 6009< / td > < td class = "benchmarkresult" > 8127< / td > < td class = "benchmarkresult" > 8251< / td > < td class = "benchmarkresult" > 20059< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- in lstringa< 8>|64< span class = "tooltiptext code" > template< size_t N, size_t Count>
void ReplaceAllLongerSimString(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
lstringa< N> result = big_source;
result.replace(" bb" , " ----" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 145< / td > < td class = "benchmarkresult" > 154< / td > < td class = "benchmarkresult" > 336< / td > < td class = "benchmarkresult" > 331< / td > < td class = "benchmarkresult" > 734< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- in lstringa< 8>|256< span class = "tooltiptext code" > template< size_t N, size_t Count>
void ReplaceAllLongerSimString(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
lstringa< N> result = big_source;
result.replace(" bb" , " ----" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 435< / td > < td class = "benchmarkresult" > 459< / td > < td class = "benchmarkresult" > 659< / td > < td class = "benchmarkresult" > 685< / td > < td class = "benchmarkresult" > 2096< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- in lstringa< 8>|512< span class = "tooltiptext code" > template< size_t N, size_t Count>
void ReplaceAllLongerSimString(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
lstringa< N> result = big_source;
result.replace(" bb" , " ----" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 825< / td > < td class = "benchmarkresult" > 850< / td > < td class = "benchmarkresult" > 1091< / td > < td class = "benchmarkresult" > 1198< / td > < td class = "benchmarkresult" > 3770< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- in lstringa< 8>|1024< span class = "tooltiptext code" > template< size_t N, size_t Count>
void ReplaceAllLongerSimString(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
lstringa< N> result = big_source;
result.replace(" bb" , " ----" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1713< / td > < td class = "benchmarkresult" > 1775< / td > < td class = "benchmarkresult" > 1937< / td > < td class = "benchmarkresult" > 2107< / td > < td class = "benchmarkresult" > 7288< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- in lstringa< 8>|2048< span class = "tooltiptext code" > template< size_t N, size_t Count>
void ReplaceAllLongerSimString(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
lstringa< N> result = big_source;
result.replace(" bb" , " ----" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 3055< / td > < td class = "benchmarkresult" > 3322< / td > < td class = "benchmarkresult" > 3647< / td > < td class = "benchmarkresult" > 4065< / td > < td class = "benchmarkresult" > 13342< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- by init stringa|64< span class = "tooltiptext code" > template< size_t Count>
void ReplaceAllLongerSimStringExpr(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), " bb" , " ----" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 117< / td > < td class = "benchmarkresult" > 124< / td > < td class = "benchmarkresult" > 212< / td > < td class = "benchmarkresult" > 230< / td > < td class = "benchmarkresult" > 498< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- by init stringa|256< span class = "tooltiptext code" > template< size_t Count>
void ReplaceAllLongerSimStringExpr(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), " bb" , " ----" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 398< / td > < td class = "benchmarkresult" > 483< / td > < td class = "benchmarkresult" > 559< / td > < td class = "benchmarkresult" > 582< / td > < td class = "benchmarkresult" > 1896< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- by init stringa|512< span class = "tooltiptext code" > template< size_t Count>
void ReplaceAllLongerSimStringExpr(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), " bb" , " ----" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 803< / td > < td class = "benchmarkresult" > 888< / td > < td class = "benchmarkresult" > 1035< / td > < td class = "benchmarkresult" > 1007< / td > < td class = "benchmarkresult" > 3611< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- by init stringa|1024< span class = "tooltiptext code" > template< size_t Count>
void ReplaceAllLongerSimStringExpr(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), " bb" , " ----" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1624< / td > < td class = "benchmarkresult" > 1787< / td > < td class = "benchmarkresult" > 1850< / td > < td class = "benchmarkresult" > 1913< / td > < td class = "benchmarkresult" > 6933< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to ---- by init stringa|2048< span class = "tooltiptext code" > template< size_t Count>
void ReplaceAllLongerSimStringExpr(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), " bb" , " ----" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 3156< / td > < td class = "benchmarkresult" > 3741< / td > < td class = "benchmarkresult" > 3423< / td > < td class = "benchmarkresult" > 3605< / td > < td class = "benchmarkresult" > 13812< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' R e p l a c e A l l S t r T o L o n g e r S i z e ' ] = { i d : ' b s 2 0 ' , t e s t s : [
{name:'replace bb to ---- in std::string|64',data:[164,174,236,248,759]},
{name:'replace bb to ---- in std::string|256',data:[531,511,780,807,2371]},
{name:'replace bb to ---- in std::string|512',data:[1217,1180,1449,1551,4397]},
{name:'replace bb to ---- in std::string|1024',data:[2374,2244,3239,3622,8983]},
{name:'replace bb to ---- in std::string|2048',data:[5735,6009,8127,8251,20059]},
{name:'replace bb to ---- in lstringa< 8 > |64',data:[145,154,336,331,734]},
{name:'replace bb to ---- in lstringa< 8 > |256',data:[435,459,659,685,2096]},
{name:'replace bb to ---- in lstringa< 8 > |512',data:[825,850,1091,1198,3770]},
{name:'replace bb to ---- in lstringa< 8 > |1024',data:[1713,1775,1937,2107,7288]},
{name:'replace bb to ---- in lstringa< 8 > |2048',data:[3055,3322,3647,4065,13342]},
{name:'replace bb to ---- by init stringa|64',data:[117,124,212,230,498]},
{name:'replace bb to ---- by init stringa|256',data:[398,483,559,582,1896]},
{name:'replace bb to ---- by init stringa|512',data:[803,888,1035,1007,3611]},
{name:'replace bb to ---- by init stringa|1024',data:[1624,1787,1850,1913,6933]},
{name:'replace bb to ---- by init stringa|2048',data:[3156,3741,3423,3605,13812]}
2025-04-05 14:21:11 +00:00
]}< / script >
2025-11-26 19:15:50 +00:00
< div class = "benchset" id = "bs21" > < h4 > Replace All Str To Same Size< / h4 >
2025-04-05 14:21:11 +00:00
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- in std::string|64< span class = "tooltiptext code" > template< size_t Long>
void ReplaceAllEqualStdString(benchmark::State& state) {
std::string_view source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
std::string_view sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
std::string_view pattern = " bb" ;
std::string_view repl = " --" ;
std::string big_source, big_sample;
for (int i = 0; i < Long; i++) {
big_source += source;
big_sample += sample;
}
for (auto _: state) {
std::string result{big_source};
size_t start_pos = 0;
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
result.replace(start_pos, pattern.length(), repl);
start_pos += repl.length();
}
#ifdef CHECK_RESULT
if (result != big_sample) {
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 119< / td > < td class = "benchmarkresult" > 118< / td > < td class = "benchmarkresult" > 192< / td > < td class = "benchmarkresult" > 206< / td > < td class = "benchmarkresult" > 545< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- in std::string|256< span class = "tooltiptext code" > template< size_t Long>
void ReplaceAllEqualStdString(benchmark::State& state) {
std::string_view source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
std::string_view sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
std::string_view pattern = " bb" ;
std::string_view repl = " --" ;
std::string big_source, big_sample;
for (int i = 0; i < Long; i++) {
big_source += source;
big_sample += sample;
}
for (auto _: state) {
std::string result{big_source};
size_t start_pos = 0;
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
result.replace(start_pos, pattern.length(), repl);
start_pos += repl.length();
}
#ifdef CHECK_RESULT
if (result != big_sample) {
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 415< / td > < td class = "benchmarkresult" > 370< / td > < td class = "benchmarkresult" > 495< / td > < td class = "benchmarkresult" > 533< / td > < td class = "benchmarkresult" > 1885< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- in std::string|512< span class = "tooltiptext code" > template< size_t Long>
void ReplaceAllEqualStdString(benchmark::State& state) {
std::string_view source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
std::string_view sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
std::string_view pattern = " bb" ;
std::string_view repl = " --" ;
std::string big_source, big_sample;
for (int i = 0; i < Long; i++) {
big_source += source;
big_sample += sample;
}
for (auto _: state) {
std::string result{big_source};
size_t start_pos = 0;
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
result.replace(start_pos, pattern.length(), repl);
start_pos += repl.length();
}
#ifdef CHECK_RESULT
if (result != big_sample) {
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 783< / td > < td class = "benchmarkresult" > 739< / td > < td class = "benchmarkresult" > 854< / td > < td class = "benchmarkresult" > 968< / td > < td class = "benchmarkresult" > 3368< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- in std::string|1024< span class = "tooltiptext code" > template< size_t Long>
void ReplaceAllEqualStdString(benchmark::State& state) {
std::string_view source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
std::string_view sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
std::string_view pattern = " bb" ;
std::string_view repl = " --" ;
std::string big_source, big_sample;
for (int i = 0; i < Long; i++) {
big_source += source;
big_sample += sample;
}
for (auto _: state) {
std::string result{big_source};
size_t start_pos = 0;
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
result.replace(start_pos, pattern.length(), repl);
start_pos += repl.length();
}
#ifdef CHECK_RESULT
if (result != big_sample) {
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1499< / td > < td class = "benchmarkresult" > 1423< / td > < td class = "benchmarkresult" > 1670< / td > < td class = "benchmarkresult" > 1840< / td > < td class = "benchmarkresult" > 6925< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- in std::string|2048< span class = "tooltiptext code" > template< size_t Long>
void ReplaceAllEqualStdString(benchmark::State& state) {
std::string_view source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
std::string_view sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
std::string_view pattern = " bb" ;
std::string_view repl = " --" ;
std::string big_source, big_sample;
for (int i = 0; i < Long; i++) {
big_source += source;
big_sample += sample;
}
for (auto _: state) {
std::string result{big_source};
size_t start_pos = 0;
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
result.replace(start_pos, pattern.length(), repl);
start_pos += repl.length();
}
#ifdef CHECK_RESULT
if (result != big_sample) {
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 2960< / td > < td class = "benchmarkresult" > 2898< / td > < td class = "benchmarkresult" > 3178< / td > < td class = "benchmarkresult" > 3641< / td > < td class = "benchmarkresult" > 13051< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- in lstringa< 8>|64< span class = "tooltiptext code" > template< size_t N, size_t Long>
void ReplaceAllEqualSimString(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
lstringa< 2048> big_source{Long, source}, big_sample{Long, sample};
for (auto _: state) {
lstringa< N> result = big_source;
result.replace(" bb" , " --" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 101< / td > < td class = "benchmarkresult" > 99.1< / td > < td class = "benchmarkresult" > 192< / td > < td class = "benchmarkresult" > 200< / td > < td class = "benchmarkresult" > 483< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- in lstringa< 8>|256< span class = "tooltiptext code" > template< size_t N, size_t Long>
void ReplaceAllEqualSimString(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
lstringa< 2048> big_source{Long, source}, big_sample{Long, sample};
for (auto _: state) {
lstringa< N> result = big_source;
result.replace(" bb" , " --" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 326< / td > < td class = "benchmarkresult" > 301< / td > < td class = "benchmarkresult" > 446< / td > < td class = "benchmarkresult" > 475< / td > < td class = "benchmarkresult" > 1542< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- in lstringa< 8>|512< span class = "tooltiptext code" > template< size_t N, size_t Long>
void ReplaceAllEqualSimString(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
lstringa< 2048> big_source{Long, source}, big_sample{Long, sample};
for (auto _: state) {
lstringa< N> result = big_source;
result.replace(" bb" , " --" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 569< / td > < td class = "benchmarkresult" > 566< / td > < td class = "benchmarkresult" > 789< / td > < td class = "benchmarkresult" > 816< / td > < td class = "benchmarkresult" > 2827< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- in lstringa< 8>|1024< span class = "tooltiptext code" > template< size_t N, size_t Long>
void ReplaceAllEqualSimString(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
lstringa< 2048> big_source{Long, source}, big_sample{Long, sample};
for (auto _: state) {
lstringa< N> result = big_source;
result.replace(" bb" , " --" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1128< / td > < td class = "benchmarkresult" > 1104< / td > < td class = "benchmarkresult" > 1526< / td > < td class = "benchmarkresult" > 1508< / td > < td class = "benchmarkresult" > 5568< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- in lstringa< 8>|2048< span class = "tooltiptext code" > template< size_t N, size_t Long>
void ReplaceAllEqualSimString(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
lstringa< 2048> big_source{Long, source}, big_sample{Long, sample};
for (auto _: state) {
lstringa< N> result = big_source;
result.replace(" bb" , " --" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 2155< / td > < td class = "benchmarkresult" > 2088< / td > < td class = "benchmarkresult" > 2820< / td > < td class = "benchmarkresult" > 2969< / td > < td class = "benchmarkresult" > 10863< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- by init stringa|64< span class = "tooltiptext code" > template< size_t Count>
void ReplaceAllEqualSimStringExpr(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
ssa pattern = " bb" ;
ssa repl = " --" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), " bb" , " --" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 86.9< / td > < td class = "benchmarkresult" > 99.6< / td > < td class = "benchmarkresult" > 162< / td > < td class = "benchmarkresult" > 192< / td > < td class = "benchmarkresult" > 363< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- by init stringa|256< span class = "tooltiptext code" > template< size_t Count>
void ReplaceAllEqualSimStringExpr(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
ssa pattern = " bb" ;
ssa repl = " --" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), " bb" , " --" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 232< / td > < td class = "benchmarkresult" > 274< / td > < td class = "benchmarkresult" > 354< / td > < td class = "benchmarkresult" > 392< / td > < td class = "benchmarkresult" > 1249< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- by init stringa|512< span class = "tooltiptext code" > template< size_t Count>
void ReplaceAllEqualSimStringExpr(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
ssa pattern = " bb" ;
ssa repl = " --" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), " bb" , " --" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 441< / td > < td class = "benchmarkresult" > 527< / td > < td class = "benchmarkresult" > 600< / td > < td class = "benchmarkresult" > 660< / td > < td class = "benchmarkresult" > 2243< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- by init stringa|1024< span class = "tooltiptext code" > template< size_t Count>
void ReplaceAllEqualSimStringExpr(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
ssa pattern = " bb" ;
ssa repl = " --" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), " bb" , " --" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 883< / td > < td class = "benchmarkresult" > 1029< / td > < td class = "benchmarkresult" > 1079< / td > < td class = "benchmarkresult" > 1196< / td > < td class = "benchmarkresult" > 4204< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > replace bb to -- by init stringa|2048< span class = "tooltiptext code" > template< size_t Count>
void ReplaceAllEqualSimStringExpr(benchmark::State& state) {
ssa source = " aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba" ;
ssa sample = " aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a" ;
ssa pattern = " bb" ;
ssa repl = " --" ;
2025-11-26 19:15:50 +00:00
2025-04-05 14:21:11 +00:00
lstringa< 2048> big_source{Count, source}, big_sample{Count, sample};
for (auto _: state) {
stringa result = e_repl(big_source.to_str(), " bb" , " --" );
#ifdef CHECK_RESULT
if (result.to_str() != big_sample) {
std::cout < < result.length() < < " : " < < result < < " \n\n" < < big_sample.length() < < " : " < < big_sample < < " \n\n" ;
state.SkipWithError(" error in replace" );
break;
}
#endif
benchmark::DoNotOptimize(result);
benchmark::DoNotOptimize(source);
benchmark::DoNotOptimize(pattern);
benchmark::DoNotOptimize(repl);
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < / td > < td class = "benchmarkresult" > 1670< / td > < td class = "benchmarkresult" > 2041< / td > < td class = "benchmarkresult" > 2067< / td > < td class = "benchmarkresult" > 2432< / td > < td class = "benchmarkresult" > 8206< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' R e p l a c e A l l S t r T o S a m e S i z e ' ] = { i d : ' b s 2 1 ' , t e s t s : [
{name:'replace bb to -- in std::string|64',data:[119,118,192,206,545]},
{name:'replace bb to -- in std::string|256',data:[415,370,495,533,1885]},
{name:'replace bb to -- in std::string|512',data:[783,739,854,968,3368]},
{name:'replace bb to -- in std::string|1024',data:[1499,1423,1670,1840,6925]},
{name:'replace bb to -- in std::string|2048',data:[2960,2898,3178,3641,13051]},
{name:'replace bb to -- in lstringa< 8 > |64',data:[101,99.1,192,200,483]},
{name:'replace bb to -- in lstringa< 8 > |256',data:[326,301,446,475,1542]},
{name:'replace bb to -- in lstringa< 8 > |512',data:[569,566,789,816,2827]},
{name:'replace bb to -- in lstringa< 8 > |1024',data:[1128,1104,1526,1508,5568]},
{name:'replace bb to -- in lstringa< 8 > |2048',data:[2155,2088,2820,2969,10863]},
{name:'replace bb to -- by init stringa|64',data:[86.9,99.6,162,192,363]},
{name:'replace bb to -- by init stringa|256',data:[232,274,354,392,1249]},
{name:'replace bb to -- by init stringa|512',data:[441,527,600,660,2243]},
{name:'replace bb to -- by init stringa|1024',data:[883,1029,1079,1196,4204]},
{name:'replace bb to -- by init stringa|2048',data:[1670,2041,2067,2432,8206]}
2025-04-05 14:21:11 +00:00
]}< / script >
2025-11-26 19:15:50 +00:00
< div class = "benchset" id = "bs22" > < h4 > Hash Map insert and find< / h4 >
2025-04-05 14:21:11 +00:00
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > hashStrMapA< size_t> emplace & find stringa;< span class = "tooltiptext code" > void HashMapSimStr(benchmark::State& state) {
for (auto _: state) {
hashStrMapA< size_t> store;
for (size_t idx = 0; idx < bs_sim.size(); idx++) {
store.try_emplace(bs_sim[idx], idx);
}
#ifdef CHECK_RESULT
if (store.size() != bs_sim.size()) {
state.SkipWithError(" bad inserts" );
}
#endif
for (size_t idx = 0; idx < bs_sim.size(); idx++) {
auto find = store.find(bs_sim[idx]);
size_t res = find->second;
#ifdef CHECK_RESULT
if (res != idx) {
state.SkipWithError(" bad find" );
}
#endif
benchmark::DoNotOptimize(res);
}
}
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Вставляем в hashStrMapA 10000 stringa длиной от 30 до 50
2025-11-26 19:15:50 +00:00
символов, а потом ищем их в ней< / span > < / span > < / td > < td class = "benchmarkresult" > 3565051< / td > < td class = "benchmarkresult" > 3720924< / td > < td class = "benchmarkresult" > 3852886< / td > < td class = "benchmarkresult" > 4270225< / td > < td class = "benchmarkresult" > 5371717< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::unordered_map< std::string, size_t> emplace & find std::string;< span class = "tooltiptext code" > void HashMapStdStr(benchmark::State& state) {
for (auto _: state) {
std::unordered_map< std::string, size_t> store;
for (size_t idx = 0; idx < bs_std.size(); idx++) {
store.try_emplace(bs_std[idx], idx);
}
#ifdef CHECK_RESULT
if (store.size() != bs_std.size()) {
state.SkipWithError(" bad inserts" );
}
#endif
for (size_t idx = 0; idx < bs_std.size(); idx++) {
auto find = store.find(bs_std[idx]);
size_t res = find->second;
#ifdef CHECK_RESULT
if (res != idx) {
state.SkipWithError(" bad find" );
}
#endif
benchmark::DoNotOptimize(res);
}
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Т о же самое c std::string и std::unordered_map< / span > < / span > < / td > < td class = "benchmarkresult" > 3504581< / td > < td class = "benchmarkresult" > 3624563< / td > < td class = "benchmarkresult" > 5329837< / td > < td class = "benchmarkresult" > 5385050< / td > < td class = "benchmarkresult" > 5883527< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > hashStrMapA< size_t> emplace & find ssa;< span class = "tooltiptext code" > void HashMapSimSsa(benchmark::State& state) {
for (auto _: state) {
hashStrMapA< size_t> store;
for (size_t idx = 0; idx < bs_sim.size(); idx++) {
store.emplace(bs_sim[idx], idx);
}
#ifdef CHECK_RESULT
if (store.size() != bs_sim.size()) {
state.SkipWithError(" bad inserts" );
}
#endif
for (size_t idx = 0; idx < bs_sim.size(); idx++) {
ssa key = bs_sim[idx];
auto find = store.find(key);
size_t res = find->second;
#ifdef CHECK_RESULT
if (res != idx) {
state.SkipWithError(" bad find" );
}
#endif
benchmark::DoNotOptimize(res);
}
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Теперь вставляем stringa, а ищем ssa< / span > < / span > < / td > < td class = "benchmarkresult" > 3648733< / td > < td class = "benchmarkresult" > 3730268< / td > < td class = "benchmarkresult" > 3511046< / td > < td class = "benchmarkresult" > 3953790< / td > < td class = "benchmarkresult" > 5376097< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > std::unordered_map< std::string, size_t> emplace & find std::string_view;< span class = "tooltiptext code" > void HashMapStdStrView(benchmark::State& state) {
for (auto _: state) {
std::unordered_map< std::string, size_t> store;
for (size_t idx = 0; idx < bs_std.size(); idx++) {
store.emplace(bs_std[idx], idx);
}
#ifdef CHECK_RESULT
if (store.size() != bs_std.size()) {
state.SkipWithError(" bad inserts" );
}
#endif
for (size_t idx = 0; idx < bs_std.size(); idx++) {
std::string_view key = bs_std[idx];
auto find = store.find(std::string{key});
size_t res = find->second;
#ifdef CHECK_RESULT
if (res != idx) {
state.SkipWithError(" bad find" );
}
#endif
benchmark::DoNotOptimize(res);
}
}
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Вставляем std::string, а ищем std::string_view< / span > < / span > < / td > < td class = "benchmarkresult" > 4252438< / td > < td class = "benchmarkresult" > 4036697< / td > < td class = "benchmarkresult" > 6336347< / td > < td class = "benchmarkresult" > 6874509< / td > < td class = "benchmarkresult" > 6884220< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' H a s h M a p i n s e r t a n d f i n d ' ] = { i d : ' b s 2 2 ' , t e s t s : [
{name:'hashStrMapA< size_t > emplace & find stringa;',data:[3565051,3720924,3852886,4270225,5371717]},
{name:'std::unordered_map< std::string , size_t > emplace & find std::string;',data:[3504581,3624563,5329837,5385050,5883527]},
{name:'hashStrMapA< size_t > emplace & find ssa;',data:[3648733,3730268,3511046,3953790,5376097]},
{name:'std::unordered_map< std::string , size_t > emplace & find std::string_view;',data:[4252438,4036697,6336347,6874509,6884220]}
2025-04-05 14:21:11 +00:00
]}< / script >
2025-11-26 19:15:50 +00:00
< div class = "benchset" id = "bs23" > < h4 > Build Full Func Name< / h4 >
2025-04-05 14:21:11 +00:00
< table > < thead > < tr > < th > Benchmark name< / th > < th width = "5%" > Comment< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-21< / th > < th width = "8%" > Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-13< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, Clang-19< / th > < th width = "8%" > Xeon E5-2682 v4, Windows 10, MSVC-19< / th > < th width = "8%" > Xeon E5-2682 v4, WASM Chrome, Clang-21< / th > < / tr > < / thead > < tbody >
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Build func full name std::string;< span class = "tooltiptext code" > std::string build_full_name_std() const {
std::string str{has_ret_type_resolver ? " any" sv : type_names_sv[(unsigned)ret_type]};
str += " " ;
str += std_name;
str += " (" ;
bool add_comma = false;
for (const auto& param : params) {
if (add_comma) {
str += " , " ;
}
if (param.optional) {
str += " [" ;
}
param.allowed_types.to_stdstr(str);
if (param.optional) {
str += " ]" ;
}
add_comma = true;
}
if (unlim_params) {
if (add_comma) {
str += " , " ;
}
str += " ..." ;
}
str += " )" ;
//std::cout < < " Len=" < < str.length() < < " , Cap=" < < str.capacity() < < " \n" ;
return str;
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Обыденная задача, подобные часто могут встретится в работе:
По неким данным сгенерировать текст. В этом случае по данным
о неких функциях сформировать их полное имя с типами параметров и
2025-11-26 19:15:50 +00:00
возвращаемого значения. Алгоритм на std::string.< / span > < / span > < / td > < td class = "benchmarkresult" > 733< / td > < td class = "benchmarkresult" > 1031< / td > < td class = "benchmarkresult" > 1581< / td > < td class = "benchmarkresult" > 1651< / td > < td class = "benchmarkresult" > 4861< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Build func full name std::string 1;< span class = "tooltiptext code" > std::string build_full_name_std1() const {
std::string str{has_ret_type_resolver ? " any" sv : type_names_sv[(unsigned)ret_type]};
str += " " + std_name + " (" ;
bool add_comma = false;
for (const auto& param : params) {
if (add_comma) {
str += " , " ;
}
if (param.optional) {
str += " [" ;
}
param.allowed_types.to_stdstr(str);
if (param.optional) {
str += " ]" ;
}
add_comma = true;
}
if (unlim_params) {
if (add_comma) {
str += " , " ;
}
str += " ..." ;
}
str += " )" ;
//std::cout < < " Len=" < < str.length() < < " , Cap=" < < str.capacity() < < " \n" ;
return str;
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Почти тот же алгоритм, но несколько последовательных
2025-11-26 19:15:50 +00:00
+= к строке заменены на одно += + + +.< / span > < / span > < / td > < td class = "benchmarkresult" > 829< / td > < td class = "benchmarkresult" > 999< / td > < td class = "benchmarkresult" > 1654< / td > < td class = "benchmarkresult" > 1706< / td > < td class = "benchmarkresult" > 5220< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Build func full name std::stream;< span class = "tooltiptext code" > std::string build_full_name_stream() const {
std::ostringstream str;
if (has_ret_type_resolver) {
str < < " any" ;
} else {
str < < type_names_sv[(unsigned)ret_type];
}
str < < " " < < std_name < < " (" ;
bool add_comma = false;
for (const auto& param : params) {
if (add_comma) {
str < < " , " ;
}
if (param.optional) {
str < < " [" ;
}
param.allowed_types.to_stream(str);
if (param.optional) {
str < < " ]" ;
}
add_comma = true;
}
if (unlim_params) {
if (add_comma) {
str < < " , " ;
}
str < < " ..." ;
}
str < < " )" ;
return str.str();
2025-11-26 19:15:50 +00:00
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Строим имя функции через std::ostringstream и < < < / span > < / span > < / td > < td class = "benchmarkresult" > 2554< / td > < td class = "benchmarkresult" > 2626< / td > < td class = "benchmarkresult" > 8195< / td > < td class = "benchmarkresult" > 9950< / td > < td class = "benchmarkresult" > 16474< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Build func full name stringa;< span class = "tooltiptext code" > stringa build_full_name() const {
lstringa< 512> str = e_choice(has_ret_type_resolver, " any" , type_names[(unsigned)ret_type]) + " " + name + " (" ;
bool add_comma = false;
for (const auto& param : params) {
str += e_if(add_comma, " , " ) + e_if(param.optional, " [" );
param.allowed_types.to_simstr(str);
if (param.optional) {
str += " ]" ;
}
add_comma = true;
}
return str + e_if(unlim_params, e_if(add_comma, " , " ) + " ..." ) + " )" ;
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Реализация на simstr строках и строковых выражениях.
2025-11-26 19:15:50 +00:00
Инфа о параметрах добавляется в текущую строку< / span > < / span > < / td > < td class = "benchmarkresult" > 525< / td > < td class = "benchmarkresult" > 602< / td > < td class = "benchmarkresult" > 859< / td > < td class = "benchmarkresult" > 948< / td > < td class = "benchmarkresult" > 2853< / td > < / tr >
2025-04-05 14:21:11 +00:00
< tr > < td class = "benchmarkname" > < span class = "tooltip" > Build func full name stringa 1;< span class = "tooltiptext code" > stringa build_full_name1() const {
lstringa< 512> str = e_choice(has_ret_type_resolver, " any" , type_names[(unsigned)ret_type]) + " " + name + " (" ;
bool add_comma = false;
for (const auto& param : params) {
str += e_if(add_comma, " , " ) + e_if(param.optional, " [" ) + param.allowed_types.get_simstr() + e_if(param.optional, " ]" );
add_comma = true;
}
return str + e_if(unlim_params, e_if(add_comma, " , " ) + " ..." ) + " )" ;
}< / span > < / span > < / td > < td > < span class = "tooltip info" > >> < span class = "tooltiptext" > Реализация на simstr строках и строковых выражениях.
Инфа о параметрах добавляется во временную строку, а потом
разом добавляется в текущую строку. Позволяет операции в цикле
2025-11-26 19:15:50 +00:00
записать в одну строку, но чуть проигрывает по времени выполнения.< / span > < / span > < / td > < td class = "benchmarkresult" > 672< / td > < td class = "benchmarkresult" > 674< / td > < td class = "benchmarkresult" > 1015< / td > < td class = "benchmarkresult" > 1108< / td > < td class = "benchmarkresult" > 3292< / td > < / tr >
< / tbody > < / table > < / div > < script > b e n c h _ s e t s [ ' B u i l d F u l l F u n c N a m e ' ] = { i d : ' b s 2 3 ' , t e s t s : [
{name:'Build func full name std::string;',data:[733,1031,1581,1651,4861]},
{name:'Build func full name std::string 1;',data:[829,999,1654,1706,5220]},
{name:'Build func full name std::stream;',data:[2554,2626,8195,9950,16474]},
{name:'Build func full name stringa;',data:[525,602,859,948,2853]},
{name:'Build func full name stringa 1;',data:[672,674,1015,1108,3292]}
]}< / script > < / body > < / html >