mirror of https://github.com/orefkov/simstr.git
4428 lines
311 KiB
HTML
4428 lines
311 KiB
HTML
<html>
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<link href="results.css" rel="stylesheet" />
|
||
<title>SimStr benchmarks results</title>
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||
<script>
|
||
let bench_sets = {};
|
||
let activeBuilder = buildTestsByPlatformsBar;
|
||
let buildAsLine = {
|
||
"Copy not literal Str with N symbols": "Length of the copied string",
|
||
"Replace All Str To Longer Size": "Length of the string to be replaced",
|
||
"Replace All Str To Same Size": "Length of the string to be replaced"
|
||
};
|
||
function hl() {
|
||
document.querySelectorAll('.tooltiptext.code').forEach((el) => {
|
||
hljs.highlightElement(el);
|
||
});
|
||
}
|
||
function addBarChart(id, data) {
|
||
let canvas = document.getElementById('chart' + id);
|
||
new Chart(canvas, {
|
||
type: 'bar',
|
||
data: data,
|
||
options: {
|
||
scales: {
|
||
y: {
|
||
beginAtZero: true
|
||
},
|
||
x: {
|
||
title: {
|
||
text: "Time (ns)",
|
||
display: true
|
||
}
|
||
}
|
||
},
|
||
indexAxis: 'y',
|
||
plugins: {
|
||
legend: {
|
||
position: 'right',
|
||
labels: {
|
||
font: {
|
||
family: "'Cascadia Code', Consolas, 'Courier New', Courier, monospace"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
function platformChecked(idx) {
|
||
return document.getElementById('pl' + idx).checked;
|
||
}
|
||
function buildPlatformsByTestsBar(bsName) {
|
||
if (buildAsLine[bsName]) {
|
||
buildPlatformsByTestsLine(bsName, buildAsLine[bsName]);
|
||
return;
|
||
}
|
||
let data = { labels: [], datasets: [] };
|
||
for (const i in platform_names) {
|
||
if (platformChecked(i))
|
||
data.datasets.push({ label: platform_names[i], data: [], borderWidth: 1 });
|
||
}
|
||
let bs = bench_sets[bsName];
|
||
for (const test of bs.tests) {
|
||
data.labels.push(test.name);
|
||
let ds = 0;
|
||
for (const i in test.data) {
|
||
if (platformChecked(i)) {
|
||
data.datasets[ds++].data.push(test.data[i]);
|
||
}
|
||
}
|
||
}
|
||
addBarChart(bs.id, data);
|
||
}
|
||
function buildTestsByPlatformsBar(bsName) {
|
||
if (buildAsLine[bsName], buildAsLine[bsName]) {
|
||
buildTestsByPlatformsLine(bsName, buildAsLine[bsName]);
|
||
return;
|
||
}
|
||
let data = { labels: [], datasets: [] };
|
||
let bs = bench_sets[bsName];
|
||
for (const test of bs.tests) {
|
||
data.datasets.push({ label: test.name, data: [], borderWidth: 1 });
|
||
}
|
||
for (const i in platform_names) {
|
||
if (platformChecked(i)) {
|
||
data.labels.push(platform_names[i]);
|
||
for (const j in bs.tests) {
|
||
data.datasets[j].data.push(bs.tests[j].data[i]);
|
||
}
|
||
}
|
||
}
|
||
addBarChart(bs.id, data);
|
||
}
|
||
function buildCanvas(plCount) {
|
||
document.querySelectorAll("canvas.bench_chart").forEach(e => e.remove());
|
||
for (var bs_name in bench_sets) {
|
||
let bs = bench_sets[bs_name];
|
||
if (plCount) {
|
||
let canvas = document.createElement('canvas');
|
||
canvas.id = "chart" + bs.id;
|
||
canvas.classList.add('bench_chart');
|
||
let h = 20 * plCount * bs.tests.length;
|
||
canvas.style.width = "100%";
|
||
canvas.style.height = h + "px";
|
||
canvas.height = h * devicePixelRatio;
|
||
document.getElementById(bs.id).after(canvas);
|
||
}
|
||
}
|
||
}
|
||
function addLineChart(canvas, data, title, scaleTitle) {
|
||
new Chart(canvas, {
|
||
type: 'line',
|
||
data: data,
|
||
options: {
|
||
scales: {
|
||
y: {
|
||
beginAtZero: true,
|
||
title: {
|
||
text: scaleTitle,
|
||
display: true
|
||
}
|
||
},
|
||
x: {
|
||
title: {
|
||
text: "Time (ns)",
|
||
display: true
|
||
}
|
||
}
|
||
},
|
||
indexAxis: 'y',
|
||
plugins: {
|
||
title: {
|
||
display: true,
|
||
text: title,
|
||
},
|
||
legend: {
|
||
position: 'right',
|
||
labels: {
|
||
font: {
|
||
family: "'Cascadia Code', Consolas, 'Courier New', Courier, monospace"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
function buildTestsByPlatformsLineOne(bs, canvas, plIdx, scaleTitle) {
|
||
let data = { datasets: [] };
|
||
let prevTest = '';
|
||
let curData = undefined;
|
||
for (const test of bs.tests) {
|
||
let m = test.name.match(/(.+)[\/\|](\d+)$/);
|
||
if (m[1] != prevTest) {
|
||
prevTest = m[1];
|
||
curData = { label: prevTest, data: [], borderWidth: 1 };
|
||
data.datasets.push(curData);
|
||
}
|
||
curData.data.push([test.data[plIdx], m[2]]);
|
||
}
|
||
addLineChart(canvas, data, platform_names[plIdx], scaleTitle);
|
||
}
|
||
function buildTestsByPlatformsLine(bsName, scaleTitle) {
|
||
let bs = bench_sets[bsName];
|
||
let canvas = document.getElementById('chart' + bs.id);
|
||
let after = null;
|
||
|
||
for (const i in platform_names) {
|
||
if (platformChecked(i)) {
|
||
if (!canvas) {
|
||
canvas = document.createElement('canvas');
|
||
canvas.classList.add('bench_chart');
|
||
canvas.style.width = "100%";
|
||
after.after(canvas);
|
||
}
|
||
canvas.style.height = "300px";
|
||
canvas.height = 300 * devicePixelRatio;
|
||
buildTestsByPlatformsLineOne(bs, canvas, i, scaleTitle);
|
||
after = canvas;
|
||
canvas = null;
|
||
}
|
||
}
|
||
}
|
||
function buildPlatformsByTestsLineOne(bs, canvas, after, testData, title, scaleTitle) {
|
||
let data = { datasets: [] };
|
||
for (const i in platform_names) {
|
||
if (platformChecked(i)) {
|
||
ds = {label: platform_names[i], data: []};
|
||
for (const test of testData) {
|
||
ds.data.push([test.data[i], test.count]);
|
||
}
|
||
data.datasets.push(ds);
|
||
}
|
||
}
|
||
if (!canvas) {
|
||
canvas = document.createElement('canvas');
|
||
canvas.classList.add('bench_chart');
|
||
canvas.style.width = "100%";
|
||
after.after(canvas);
|
||
}
|
||
canvas.style.height = "300px";
|
||
canvas.height = 300 * devicePixelRatio;
|
||
addLineChart(canvas, data, title, scaleTitle);
|
||
return canvas;
|
||
}
|
||
function buildPlatformsByTestsLine(bsName, scaleTitle) {
|
||
let bs = bench_sets[bsName];
|
||
let canvas = document.getElementById('chart' + bs.id);
|
||
let after = null;
|
||
let data = [];
|
||
let prevTest = '';
|
||
for (const test of bs.tests) {
|
||
let m = test.name.match(/(.+)[\/\|](\d+)$/);
|
||
if (m[1] != prevTest) {
|
||
if (data.length) {
|
||
after = buildPlatformsByTestsLineOne(bs, canvas, after, data, prevTest, scaleTitle);
|
||
canvas = null;
|
||
}
|
||
prevTest = m[1];
|
||
data = [];
|
||
}
|
||
data.push({count: m[2], data: test.data});
|
||
}
|
||
if (data.length) {
|
||
buildPlatformsByTestsLineOne(bs, canvas, after, data, prevTest, scaleTitle);
|
||
}
|
||
}
|
||
function buildCharts() {
|
||
let plCount = 0;
|
||
for (const i in platform_names) {
|
||
if (platformChecked(i))
|
||
plCount++;
|
||
}
|
||
buildCanvas(plCount);
|
||
for (var bs_name in bench_sets) {
|
||
activeBuilder(bs_name);
|
||
}
|
||
}
|
||
function switchGrouping() {
|
||
activeBuilder = document.getElementById('gbp').checked ? buildTestsByPlatformsBar : buildPlatformsByTestsBar;
|
||
buildCharts();
|
||
}
|
||
document.addEventListener('DOMContentLoaded', (event) => {
|
||
if (!hljs) {
|
||
let scriptTag = document.createElement('script');
|
||
scriptTag.src = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js";
|
||
scriptTag.onload = hl;
|
||
scriptTag.onreadystatechange = hl;
|
||
document.body.appendChild(scriptTag);
|
||
} else {
|
||
hl();
|
||
}
|
||
if (!Chart) {
|
||
let scriptTag = document.createElement('script');
|
||
scriptTag.src = "https://cdn.jsdelivr.net/npm/chart.js";
|
||
scriptTag.onload = buildCharts;
|
||
scriptTag.onreadystatechange = buildCharts;
|
||
document.body.appendChild(scriptTag);
|
||
} else {
|
||
buildCharts();
|
||
}
|
||
});
|
||
</script>
|
||
</head><body><div class="header"><h2>simstr benchmarks results</h2>
|
||
<div style="font-size:16pt;margin:20px;text-align:center"><a href="https://github.com/orefkov/simstr">simstr</a> is a powerful and convenient library for productive work with strings in C++.</div>
|
||
<span>All times in ns.</span>
|
||
<span><a href="https://github.com/orefkov/simstr/blob/main/bench/bench_str.cpp">Source for benchmarks</a></span>
|
||
<div>Group tests by platforms in charts: <input type="checkbox" id="gbp" checked onchange="switchGrouping()"/></div><div class="test_platforms"><h3>Test configurations:</h3><ul>
|
||
<li><span class="platform">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</span><span class="tooltip">32 X 2494.22 MHz CPU s<span class="tooltiptext">CPU Caches:
|
||
L1 Data 32 KiB (x16)
|
||
L1 Instruction 32 KiB (x16)
|
||
L2 Unified 256 KiB (x16)
|
||
L3 Unified 40960 KiB (x1)
|
||
Load Average: 0.20, 0.67, 0.53
|
||
***WARNING*** ASLR is enabled, the results may have unreproducible noise in them.</span></span> Include in charts: <input type="checkbox" id="pl0" checked onchange="buildCharts()"/></li>
|
||
<li><span class="platform">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</span><span class="tooltip">32 X 2494.22 MHz CPU s<span class="tooltiptext">CPU Caches:
|
||
L1 Data 32 KiB (x16)
|
||
L1 Instruction 32 KiB (x16)
|
||
L2 Unified 256 KiB (x16)
|
||
L3 Unified 40960 KiB (x1)
|
||
Load Average: 0.28, 0.77, 0.74
|
||
***WARNING*** ASLR is enabled, the results may have unreproducible noise in them.</span></span> Include in charts: <input type="checkbox" id="pl1" checked onchange="buildCharts()"/></li>
|
||
<li><span class="platform">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</span><span class="tooltip">32 X 2494.22 MHz CPU s<span class="tooltiptext">CPU Caches:
|
||
L1 Data 32 KiB (x16)
|
||
L1 Instruction 32 KiB (x16)
|
||
L2 Unified 256 KiB (x16)
|
||
L3 Unified 40960 KiB (x1)
|
||
Load Average: 0.06, 0.09, 0.08
|
||
***WARNING*** ASLR is enabled, the results may have unreproducible noise in them.</span></span> Include in charts: <input type="checkbox" id="pl2" checked onchange="buildCharts()"/></li>
|
||
<li><span class="platform">Xeon E5-2682 v4, Windows 10, Clang-22</span><span class="tooltip">32 X 2494 MHz CPU s<span class="tooltiptext">CPU Caches:
|
||
L1 Data 32 KiB (x16)
|
||
L1 Instruction 32 KiB (x16)
|
||
L2 Unified 256 KiB (x16)
|
||
L3 Unified 40960 KiB (x1)</span></span> Include in charts: <input type="checkbox" id="pl3" checked onchange="buildCharts()"/></li>
|
||
<li><span class="platform">Xeon E5-2682 v4, Windows 10, MSVC-19</span><span class="tooltip">32 X 2494 MHz CPU s<span class="tooltiptext">CPU Caches:
|
||
L1 Data 32 KiB (x16)
|
||
L1 Instruction 32 KiB (x16)
|
||
L2 Unified 256 KiB (x16)
|
||
L3 Unified 40960 KiB (x1)</span></span> Include in charts: <input type="checkbox" id="pl4" checked onchange="buildCharts()"/></li>
|
||
<li><span class="platform">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</span><span class="tooltip">32 X 2513.96 MHz CPU s<span class="tooltiptext">Chrome/143.0.0.0 webasm</span></span> Include in charts: <input type="checkbox" id="pl5" checked onchange="buildCharts()"/></li>
|
||
</ul></div></div>
|
||
<script>const platform_names=['Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22','Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++','Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15','Xeon E5-2682 v4, Windows 10, Clang-22','Xeon E5-2682 v4, Windows 10, MSVC-19','Xeon E5-2682 v4, WASM Chrome 143, Clang-22'];</script>
|
||
|
||
|
||
<div class="benchset" id="bs1"><h4><a id="bs15359472366966513900" href="#bs15359472366966513900">#</a> Concatenate email</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L94">Concat email std::format</a><span class="tooltiptext code">std::string email_concat_format(std::string_view name, std::string_view domain, std::string_view tld) {
|
||
return std::format("{}@{}.{}", name, domain, tld);
|
||
}</span></span></td><td></td><td class="benchmarkresult">167</td><td class="benchmarkresult">170</td><td class="benchmarkresult">160</td><td class="benchmarkresult">201</td><td class="benchmarkresult">256</td><td class="benchmarkresult">483</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L109">Concat email std::stringstream</a><span class="tooltiptext code">std::string email_concat_stream(std::string_view name, std::string_view domain, std::string_view tld) {
|
||
std::stringstream s;
|
||
s << name << "@" << domain << "." << tld;
|
||
return s.str();
|
||
}</span></span></td><td></td><td class="benchmarkresult">379</td><td class="benchmarkresult">279</td><td class="benchmarkresult">321</td><td class="benchmarkresult">830</td><td class="benchmarkresult">940</td><td class="benchmarkresult">1090</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L60">Concat email stringzilla append</a><span class="tooltiptext code">sz::string email_concat_stringzilla_app(sz::string name, sz::string_view domain, sz::string_view tld) {
|
||
return name.append("@").append(domain).append(".").append(tld);
|
||
}</span></span></td><td></td><td class="benchmarkresult">143</td><td class="benchmarkresult">141</td><td class="benchmarkresult">108</td><td class="benchmarkresult">273</td><td class="benchmarkresult">287</td><td class="benchmarkresult">230</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L77">Concat email stringzilla concat</a><span class="tooltiptext code">sz::string email_concat_stringzilla_exp(sz::string name, sz::string_view domain, sz::string_view tld) {
|
||
return sz::string{name | sz::string_view{"@"} | domain | sz::string_view{"."} | tld};
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">В stringzilla тоже есть конкатенация строковыми выражениями, но не
|
||
так удобна и развита, как в simstr.
|
||
Stringzilla also has concatenation by expression templates,
|
||
but it's not as convenient or advanced as simstr.</span></span></td><td class="benchmarkresult">54.6</td><td class="benchmarkresult">55.0</td><td class="benchmarkresult">42.8</td><td class="benchmarkresult">126</td><td class="benchmarkresult">134</td><td class="benchmarkresult">92.5</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L126">Concat email std::string append</a><span class="tooltiptext code">std::string email_concat_std(std::string name, std::string_view domain, std::string_view tld) {
|
||
return name.append("@").append(domain).append(".").append(tld);
|
||
}</span></span></td><td></td><td class="benchmarkresult">73.9</td><td class="benchmarkresult">91.0</td><td class="benchmarkresult">79.2</td><td class="benchmarkresult">187</td><td class="benchmarkresult">200</td><td class="benchmarkresult">289</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L142">Concat email std::string by strexpr</a><span class="tooltiptext code">std::string email_concat_std_expr(std::string_view name, std::string_view domain, std::string_view tld) {
|
||
return +name + "@" + domain + "." + tld;
|
||
}</span></span></td><td></td><td class="benchmarkresult">46.8</td><td class="benchmarkresult">46.8</td><td class="benchmarkresult">34.4</td><td class="benchmarkresult">104</td><td class="benchmarkresult">113</td><td class="benchmarkresult">88.2</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L157">Concat email stringa</a><span class="tooltiptext code">stringa email_concat_sim_expr(ssa name, ssa domain, ssa tld) {
|
||
return name + "@" + domain + "." + tld;
|
||
}</span></span></td><td></td><td class="benchmarkresult">39.1</td><td class="benchmarkresult">38.7</td><td class="benchmarkresult">40.7</td><td class="benchmarkresult">94.4</td><td class="benchmarkresult">106</td><td class="benchmarkresult">67.4</td></tr>
|
||
</tbody></table></div><script>bench_sets['Concatenate email'] = {id:'bs1', tests:[
|
||
{name:'Concat email std::format',data:[167,170,160,201,256,483]},
|
||
{name:'Concat email std::stringstream',data:[379,279,321,830,940,1090]},
|
||
{name:'Concat email stringzilla append',data:[143,141,108,273,287,230]},
|
||
{name:'Concat email stringzilla concat',data:[54.6,55.0,42.8,126,134,92.5]},
|
||
{name:'Concat email std::string append',data:[73.9,91.0,79.2,187,200,289]},
|
||
{name:'Concat email std::string by strexpr',data:[46.8,46.8,34.4,104,113,88.2]},
|
||
{name:'Concat email stringa',data:[39.1,38.7,40.7,94.4,106,67.4]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs2"><h4><a id="bs70109915512075798510" href="#bs70109915512075798510">#</a> Concatenate string + Number + "Literal"</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L181">Concat std::string and number by std to std::string</a><span class="tooltiptext code">void ConcatStdToStd(benchmark::State& state) {
|
||
std::string s1 = "start ";
|
||
for (auto _: state) {
|
||
for (int i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
std::string str = s1 + std::to_string(i) + " end";
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">223</td><td class="benchmarkresult">242</td><td class="benchmarkresult">214</td><td class="benchmarkresult">268</td><td class="benchmarkresult">333</td><td class="benchmarkresult">1042</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L192">Concat std::string and number by StrExpr to std::string</a><span class="tooltiptext code">void ConcatSimToStd(benchmark::State& state) {
|
||
std::string s1 = "start ";
|
||
for (auto _: state) {
|
||
for (int i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
std::string str = +s1 + i + " end";
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">105</td><td class="benchmarkresult">102</td><td class="benchmarkresult">102</td><td class="benchmarkresult">160</td><td class="benchmarkresult">219</td><td class="benchmarkresult">486</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L203">Concat stringa and number by StrExpr to simstr::stringa</a><span class="tooltiptext code">void ConcatSimToSim(benchmark::State& state) {
|
||
stra s1 = "start ";
|
||
for (auto _: state) {
|
||
for (int i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
stringa str = s1 + i + " end";
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">stringa в отличии от std::string,
|
||
вмещает в SSO 23 символа вместо 15, поэтому
|
||
в конце теста std::string приходится аллоцировать память,
|
||
а в stringa весь тест входит в SSO.
|
||
Unlike std::string, stringa
|
||
holds 23 characters in SSO instead of 15, so
|
||
at the end of the std::string test, memory has to be allocated,
|
||
while in stringa , the entire test is included in SSO.</span></span></td><td class="benchmarkresult">64.9</td><td class="benchmarkresult">64.3</td><td class="benchmarkresult">72.3</td><td class="benchmarkresult">68.7</td><td class="benchmarkresult">109</td><td class="benchmarkresult">217</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L214">Concat stringa and number by e_concat to simstr::stringa</a><span class="tooltiptext code">void ConcatSimToSimConcat(benchmark::State& state) {
|
||
stra s1 = "start ";
|
||
for (auto _: state) {
|
||
for (int i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
stringa str = e_concat("", s1, i, " end");
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">72.3</td><td class="benchmarkresult">72.1</td><td class="benchmarkresult">77.7</td><td class="benchmarkresult">74.2</td><td class="benchmarkresult">121</td><td class="benchmarkresult">218</td></tr>
|
||
</tbody></table></div><script>bench_sets['Concatenate string + Number + "Literal"'] = {id:'bs2', tests:[
|
||
{name:'Concat std::string and number by std to std::string',data:[223,242,214,268,333,1042]},
|
||
{name:'Concat std::string and number by StrExpr to std::string',data:[105,102,102,160,219,486]},
|
||
{name:'Concat stringa and number by StrExpr to simstr::stringa',data:[64.9,64.3,72.3,68.7,109,217]},
|
||
{name:'Concat stringa and number by e_concat to simstr::stringa',data:[72.3,72.1,77.7,74.2,121,218]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs3"><h4><a id="bs146911715078927772520" href="#bs146911715078927772520">#</a> Concatenate string + Hex Number + "Literal"</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L231">Concat std::string and format hex number and literal to std::string</a><span class="tooltiptext code">void ConcatStdToFmtHex(benchmark::State& state) {
|
||
// We use a short string so that the longest result is 15 characters and fits in the std::string SSO buffer.
|
||
std::string s1 = "art ";
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
// It is not worked for char8_t, char16_t, char32_t :(
|
||
std::string str = s1 + std::format("{:#x}", i) + " end";
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">696</td><td class="benchmarkresult">724</td><td class="benchmarkresult">728</td><td class="benchmarkresult">725</td><td class="benchmarkresult">1030</td><td class="benchmarkresult">2057</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L244">std::format std::string and hex number by literal to std::string</a><span class="tooltiptext code">void ConcatAllFmtToHex(benchmark::State& state) {
|
||
// We use a short string so that the longest result is 15 characters and fits in the std::string SSO buffer.
|
||
std::string s1 = "art ";
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
// It is not worked for char8_t, char16_t, char32_t :(
|
||
std::string str = std::format("{}{:#x} end", s1, i);
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">828</td><td class="benchmarkresult">783</td><td class="benchmarkresult">893</td><td class="benchmarkresult">1525</td><td class="benchmarkresult">1872</td><td class="benchmarkresult">2629</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L256">Concat std::string and std::to_chars and string to std::string</a><span class="tooltiptext code">void ConcatStdToCharsHex(benchmark::State& state) {
|
||
// We use a short string so that the longest result is 15 characters and fits in the std::string SSO buffer.
|
||
std::string s1 = "art ";
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
// it worked only for char :(
|
||
char buf[40];
|
||
size_t len = std::to_chars(buf, buf + std::size(buf), i, 16).ptr - buf;
|
||
std::string str = s1 + "0x" + std::string(buf, len) + " end";
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">210</td><td class="benchmarkresult">221</td><td class="benchmarkresult">199</td><td class="benchmarkresult">188</td><td class="benchmarkresult">252</td><td class="benchmarkresult">676</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L271">Concat std::string and hex number and literal by StrExpr to std::string</a><span class="tooltiptext code">void ConcatSimToStdHex(benchmark::State& state) {
|
||
// We use a short string so that the longest result is 15 characters and fits in the std::string SSO buffer.
|
||
std::string s1 = "art ";
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
// Can work for all types of symbols
|
||
std::string str = +s1 + i / 1_f16 + " end";
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">134</td><td class="benchmarkresult">150</td><td class="benchmarkresult">125</td><td class="benchmarkresult">84.6</td><td class="benchmarkresult">115</td><td class="benchmarkresult">526</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L284">Concat stringa and hex number and literal by StrExpr to simstr::stringa</a><span class="tooltiptext code">void ConcatSimToSimHex(benchmark::State& state) {
|
||
// stringa SSO buffer is 23, but we use a short string to compare under the same conditions
|
||
stra s1 = "art ";
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
// Can work for all types of symbols
|
||
stringa str = s1 + i / 1_f16 + " end";
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">117</td><td class="benchmarkresult">120</td><td class="benchmarkresult">122</td><td class="benchmarkresult">71.4</td><td class="benchmarkresult">101</td><td class="benchmarkresult">189</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L297">Concat stringa and hex number and literal by e_concat to simstr::stringa</a><span class="tooltiptext code">void ConcatSimToSimHexC(benchmark::State& state) {
|
||
// stringa SSO buffer is 23, but we use a short string to compare under the same conditions
|
||
stra s1 = "art ";
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
// Can work for all types of symbols
|
||
stringa str = e_concat("", s1, i / 1_f16, " end");
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">128</td><td class="benchmarkresult">124</td><td class="benchmarkresult">125</td><td class="benchmarkresult">76.9</td><td class="benchmarkresult">108</td><td class="benchmarkresult">198</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L310">Subst stringa and hex number by e_subst literal to simstr::stringa</a><span class="tooltiptext code">void ConcatSimToSimHexS(benchmark::State& state) {
|
||
// stringa SSO buffer is 23, but we use a short string to compare under the same conditions
|
||
stra s1 = "art ";
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
stringa str = e_subst("{}{} end", s1, i / 1_f16);
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">193</td><td class="benchmarkresult">187</td><td class="benchmarkresult">172</td><td class="benchmarkresult">149</td><td class="benchmarkresult">173</td><td class="benchmarkresult">355</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L322">Subst stringa and hex number by e_vsubst stra to simstr::stringa</a><span class="tooltiptext code">void ConcatSimToSimHexVS(benchmark::State& state) {
|
||
// stringa SSO buffer is 23, but we use a short string to compare under the same conditions
|
||
stra s1 = "art ";
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
stringa str = e_vsubst("{}{} end"_ss, s1, i / 1_f16);
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">333</td><td class="benchmarkresult">332</td><td class="benchmarkresult">280</td><td class="benchmarkresult">287</td><td class="benchmarkresult">361</td><td class="benchmarkresult">843</td></tr>
|
||
</tbody></table></div><script>bench_sets['Concatenate string + Hex Number + "Literal"'] = {id:'bs3', tests:[
|
||
{name:'Concat std::string and format hex number and literal to std::string',data:[696,724,728,725,1030,2057]},
|
||
{name:'std::format std::string and hex number by literal to std::string',data:[828,783,893,1525,1872,2629]},
|
||
{name:'Concat std::string and std::to_chars and string to std::string',data:[210,221,199,188,252,676]},
|
||
{name:'Concat std::string and hex number and literal by StrExpr to std::string',data:[134,150,125,84.6,115,526]},
|
||
{name:'Concat stringa and hex number and literal by StrExpr to simstr::stringa',data:[117,120,122,71.4,101,189]},
|
||
{name:'Concat stringa and hex number and literal by e_concat to simstr::stringa',data:[128,124,125,76.9,108,198]},
|
||
{name:'Subst stringa and hex number by e_subst literal to simstr::stringa',data:[193,187,172,149,173,355]},
|
||
{name:'Subst stringa and hex number by e_vsubst stra to simstr::stringa',data:[333,332,280,287,361,843]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs4"><h4><a id="bs32341904136562619220" href="#bs32341904136562619220">#</a> format/vformat and subst/vsubst octal number to 32 symbols result</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L344">"abcdefghihklmopqr "_ss + i / 0x8a010_fmt + " end"</a><span class="tooltiptext code">void ConcatSimToSimOct(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
stringa str = "abcdefghihklmopqr "_ss + i / 0x8a010_fmt + " end";
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">271</td><td class="benchmarkresult">278</td><td class="benchmarkresult">261</td><td class="benchmarkresult">639</td><td class="benchmarkresult">702</td><td class="benchmarkresult">414</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L353">e_subst("abcdefghihklmopqr {} end", i / 0x8a010_fmt)</a><span class="tooltiptext code">void SubstSimToSimOct(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
stringa str = e_subst("abcdefghihklmopqr {} end", i / 0x8a010_fmt);
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">357</td><td class="benchmarkresult">358</td><td class="benchmarkresult">315</td><td class="benchmarkresult">750</td><td class="benchmarkresult">810</td><td class="benchmarkresult">621</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L362">e_vsubst(pattern, i / 0x8a010_fmt)</a><span class="tooltiptext code">void VSubstSimToSimOct(benchmark::State& state) {
|
||
ssa pattern = "abcdefghihklmopqr {} end";
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
stringa str = e_vsubst(pattern, i / 0x8a010_fmt);
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">621</td><td class="benchmarkresult">608</td><td class="benchmarkresult">593</td><td class="benchmarkresult">1070</td><td class="benchmarkresult">1144</td><td class="benchmarkresult">1426</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L402">fmt::format(FMT_COMPILE("abcdefghihklmopqr {:#010o} end"), i)</a><span class="tooltiptext code">void FmtFormatComp(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
std::string str = fmt::format(FMT_COMPILE("abcdefghihklmopqr {:#010o} end"), i);
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">723</td><td class="benchmarkresult">697</td><td class="benchmarkresult">629</td><td class="benchmarkresult">1433</td><td class="benchmarkresult">1583</td><td class="benchmarkresult">2149</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L411">fmt::format("abcdefghihklmopqr {:#010o} end", i)</a><span class="tooltiptext code">void FmtFormat(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
std::string str = fmt::format("abcdefghihklmopqr {:#010o} end", i);
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
|
||
}</span></span></td><td></td><td class="benchmarkresult">842</td><td class="benchmarkresult">814</td><td class="benchmarkresult">788</td><td class="benchmarkresult">1327</td><td class="benchmarkresult">1596</td><td class="benchmarkresult">2879</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L372">std::format("abcdefghihklmopqr {:#010o} end", i)</a><span class="tooltiptext code">void FormatStdToStdOct(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
std::string str = std::format("abcdefghihklmopqr {:#010o} end", i);
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1017</td><td class="benchmarkresult">1268</td><td class="benchmarkresult">1171</td><td class="benchmarkresult">1568</td><td class="benchmarkresult">1946</td><td class="benchmarkresult">2940</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L381">std::vformat(pattern, std::make_format_args(i))</a><span class="tooltiptext code">void VFormatStdToStdOct(benchmark::State& state) {
|
||
std::string_view pattern = "abcdefghihklmopqr {:#010o} end";
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
std::string str = std::vformat(pattern, std::make_format_args(i));
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">999</td><td class="benchmarkresult">1228</td><td class="benchmarkresult">1176</td><td class="benchmarkresult">1555</td><td class="benchmarkresult">1990</td><td class="benchmarkresult">2985</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L421">std::format with std::formatted_size</a><span class="tooltiptext code">void StdFormatSize(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
size_t len = std::formatted_size("abcdefghihklmopqr {:#010o} end", i);
|
||
std::string str;
|
||
str.resize_and_overwrite(len, [&](char* p, size_t) {
|
||
std::format_to_n(str.data(), len, "abcdefghihklmopqr {:#010o} end", i);
|
||
return len;
|
||
});
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1867</td><td class="benchmarkresult">2175</td><td class="benchmarkresult">2267</td><td class="benchmarkresult">2496</td><td class="benchmarkresult">2922</td><td class="benchmarkresult">5263</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L391">strm << "abcdefghihklmopqr 0" << std::oct << std::setw(9) << std::setfill('0') << i << " end"</a><span class="tooltiptext code">void StreamStdToStdOct(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
for (unsigned i = 1; i <= 100'000; i *= 10) {
|
||
std::stringstream strm;
|
||
strm << "abcdefghihklmopqr 0" << std::oct << std::setw(9) << std::setfill('0') << i << " end";
|
||
std::string str = strm.str();
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">2074</td><td class="benchmarkresult">2608</td><td class="benchmarkresult">2021</td><td class="benchmarkresult">6707</td><td class="benchmarkresult">7026</td><td class="benchmarkresult">8433</td></tr>
|
||
</tbody></table></div><script>bench_sets['format/vformat and subst/vsubst octal number to 32 symbols result'] = {id:'bs4', tests:[
|
||
{name:'"abcdefghihklmopqr "_ss + i / 0x8a010_fmt + " end"',data:[271,278,261,639,702,414]},
|
||
{name:'e_subst("abcdefghihklmopqr {} end", i / 0x8a010_fmt)',data:[357,358,315,750,810,621]},
|
||
{name:'e_vsubst(pattern, i / 0x8a010_fmt)',data:[621,608,593,1070,1144,1426]},
|
||
{name:'fmt::format(FMT_COMPILE("abcdefghihklmopqr {:#010o} end"), i)',data:[723,697,629,1433,1583,2149]},
|
||
{name:'fmt::format("abcdefghihklmopqr {:#010o} end", i)',data:[842,814,788,1327,1596,2879]},
|
||
{name:'std::format("abcdefghihklmopqr {:#010o} end", i)',data:[1017,1268,1171,1568,1946,2940]},
|
||
{name:'std::vformat(pattern, std::make_format_args(i))',data:[999,1228,1176,1555,1990,2985]},
|
||
{name:'std::format with std::formatted_size',data:[1867,2175,2267,2496,2922,5263]},
|
||
{name:'strm << "abcdefghihklmopqr 0" << std::oct << std::setw(9) << std::setfill(\'0\') << i << " end"',data:[2074,2608,2021,6707,7026,8433]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs5"><h4><a id="bs59672599204338055190" href="#bs59672599204338055190">#</a> Concatenate string + "Literal"</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L446">Concat std::string by std to std::string</a><span class="tooltiptext code">void ConcatStdToStdS(benchmark::State& state) {
|
||
std::string s1 = "start ";
|
||
for (auto _: state) {
|
||
for (int i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
std::string str = s1 + " end";
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">51.7</td><td class="benchmarkresult">34.1</td><td class="benchmarkresult">47.9</td><td class="benchmarkresult">42.2</td><td class="benchmarkresult">55.5</td><td class="benchmarkresult">109</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L457">Concat std::string by StrExpr to std::string</a><span class="tooltiptext code">void ConcatSimToStdS(benchmark::State& state) {
|
||
std::string s1 = "start ";
|
||
for (auto _: state) {
|
||
for (int i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
std::string str = +s1 + " end";
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">36.9</td><td class="benchmarkresult">37.3</td><td class="benchmarkresult">35.3</td><td class="benchmarkresult">39.3</td><td class="benchmarkresult">77.4</td><td class="benchmarkresult">120</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L468">Concat stringa by StrExpr to stringa</a><span class="tooltiptext code">void ConcatSimToSimS(benchmark::State& state) {
|
||
stra s1 = "start ";
|
||
for (auto _: state) {
|
||
for (int i = 1; i <= 100'000; i *= 10) {
|
||
benchmark::DoNotOptimize(s1);
|
||
stringa str = s1 + " end";
|
||
benchmark::DoNotOptimize(str);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">31.6</td><td class="benchmarkresult">28.3</td><td class="benchmarkresult">27.4</td><td class="benchmarkresult">30.6</td><td class="benchmarkresult">52.2</td><td class="benchmarkresult">95.4</td></tr>
|
||
</tbody></table></div><script>bench_sets['Concatenate string + "Literal"'] = {id:'bs5', tests:[
|
||
{name:'Concat std::string by std to std::string',data:[51.7,34.1,47.9,42.2,55.5,109]},
|
||
{name:'Concat std::string by StrExpr to std::string',data:[36.9,37.3,35.3,39.3,77.4,120]},
|
||
{name:'Concat stringa by StrExpr to stringa',data:[31.6,28.3,27.4,30.6,52.2,95.4]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs6"><h4><a id="bs68116594352702954700" href="#bs68116594352702954700">#</a> Find three concatenated string in string_view</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L484">Find concat three std::string</a><span class="tooltiptext code">size_t find_pos_str(std::string_view src, std::string_view name) {
|
||
// before C++26 we can not concatenate string and string_view...
|
||
return src.find("\n- "s + std::string{name} + " -\n");
|
||
}</span></span></td><td></td><td class="benchmarkresult">112</td><td class="benchmarkresult">92.4</td><td class="benchmarkresult">119</td><td class="benchmarkresult">206</td><td class="benchmarkresult">230</td><td class="benchmarkresult">214</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L489">Find concat three strexpr</a><span class="tooltiptext code">size_t find_pos_exp(ssa src, ssa name) {
|
||
return src.find(std::string{"\n- " + name + " -\n"});
|
||
}</span></span></td><td></td><td class="benchmarkresult">52.4</td><td class="benchmarkresult">46.5</td><td class="benchmarkresult">38.2</td><td class="benchmarkresult">113</td><td class="benchmarkresult">138</td><td class="benchmarkresult">100.0</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L493">Find concat three simstr</a><span class="tooltiptext code">size_t find_pos_sim(ssa src, ssa name) {
|
||
return src.find(lstringa<200>{"\n- " + name + " -\n"});
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">Если результат конкатенации меньше 207 символов,
|
||
он собирается в буфере на стеке, без аллокации и деалокации.
|
||
If the concatenation result is less than 207 characters,
|
||
it is collected in a stack-based buffer, without allocation or deallocation.</span></span></td><td class="benchmarkresult">18.9</td><td class="benchmarkresult">17.0</td><td class="benchmarkresult">15.6</td><td class="benchmarkresult">21.2</td><td class="benchmarkresult">28.3</td><td class="benchmarkresult">58.2</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L497">Find concat three stringzilla string</a><span class="tooltiptext code">size_t find_pos_sz(sz::string_view src, sz::string_view name) {
|
||
return src.find(sz::string{"\n- "}.append(name).append(" -\n"));
|
||
}</span></span></td><td></td><td class="benchmarkresult">153</td><td class="benchmarkresult">176</td><td class="benchmarkresult">125</td><td class="benchmarkresult">215</td><td class="benchmarkresult">232</td><td class="benchmarkresult">268</td></tr>
|
||
</tbody></table></div><script>bench_sets['Find three concatenated string in string_view'] = {id:'bs6', tests:[
|
||
{name:'Find concat three std::string',data:[112,92.4,119,206,230,214]},
|
||
{name:'Find concat three strexpr',data:[52.4,46.5,38.2,113,138,100.0]},
|
||
{name:'Find concat three simstr',data:[18.9,17.0,15.6,21.2,28.3,58.2]},
|
||
{name:'Find concat three stringzilla string',data:[153,176,125,215,232,268]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs7"><h4><a id="bs145290966789248325200" href="#bs145290966789248325200">#</a> Build Type Name</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L573">BuildTypeNameStr 0/0</a><span class="tooltiptext code">std::string buildTypeNameStr(std::string_view type_name, size_t prec, size_t scale) {
|
||
std::string res{type_name};
|
||
if (prec) {
|
||
res += "(" + std::to_string(prec);
|
||
if (scale) {
|
||
res += "," + std::to_string(scale);
|
||
}
|
||
res += ")";
|
||
}
|
||
return res;
|
||
}</span></span></td><td></td><td class="benchmarkresult">7.58</td><td class="benchmarkresult">6.45</td><td class="benchmarkresult">8.65</td><td class="benchmarkresult">8.34</td><td class="benchmarkresult">17.8</td><td class="benchmarkresult">20.9</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L585">BuildTypeNameExp 0/0</a><span class="tooltiptext code">std::string buildTypeNameExp(ssa type_name, size_t prec, size_t scale) {
|
||
if (prec) {
|
||
return type_name + "(" + prec + e_if(scale, ","_ss + scale) + ")";
|
||
}
|
||
return type_name;
|
||
}</span></span></td><td></td><td class="benchmarkresult">6.94</td><td class="benchmarkresult">6.41</td><td class="benchmarkresult">6.99</td><td class="benchmarkresult">7.67</td><td class="benchmarkresult">14.4</td><td class="benchmarkresult">23.1</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L592">BuildTypeNameSim 0/0</a><span class="tooltiptext code">stringa buildTypeNameSim(ssa type_name, size_t prec, size_t scale) {
|
||
if (prec) {
|
||
return type_name + "(" + prec + e_if(scale, ","_ss + scale) + ")";
|
||
}
|
||
return type_name;
|
||
}</span></span></td><td></td><td class="benchmarkresult">5.03</td><td class="benchmarkresult">4.99</td><td class="benchmarkresult">4.97</td><td class="benchmarkresult">7.90</td><td class="benchmarkresult">15.4</td><td class="benchmarkresult">20.4</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L573">BuildTypeNameStr 10/10</a><span class="tooltiptext code">std::string buildTypeNameStr(std::string_view type_name, size_t prec, size_t scale) {
|
||
std::string res{type_name};
|
||
if (prec) {
|
||
res += "(" + std::to_string(prec);
|
||
if (scale) {
|
||
res += "," + std::to_string(scale);
|
||
}
|
||
res += ")";
|
||
}
|
||
return res;
|
||
}</span></span></td><td></td><td class="benchmarkresult">59.1</td><td class="benchmarkresult">90.0</td><td class="benchmarkresult">76.6</td><td class="benchmarkresult">79.5</td><td class="benchmarkresult">80.1</td><td class="benchmarkresult">365</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L585">BuildTypeNameExp 10/10</a><span class="tooltiptext code">std::string buildTypeNameExp(ssa type_name, size_t prec, size_t scale) {
|
||
if (prec) {
|
||
return type_name + "(" + prec + e_if(scale, ","_ss + scale) + ")";
|
||
}
|
||
return type_name;
|
||
}</span></span></td><td></td><td class="benchmarkresult">31.0</td><td class="benchmarkresult">39.0</td><td class="benchmarkresult">27.9</td><td class="benchmarkresult">33.1</td><td class="benchmarkresult">39.4</td><td class="benchmarkresult">116</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L592">BuildTypeNameSim 10/10</a><span class="tooltiptext code">stringa buildTypeNameSim(ssa type_name, size_t prec, size_t scale) {
|
||
if (prec) {
|
||
return type_name + "(" + prec + e_if(scale, ","_ss + scale) + ")";
|
||
}
|
||
return type_name;
|
||
}</span></span></td><td></td><td class="benchmarkresult">23.4</td><td class="benchmarkresult">23.6</td><td class="benchmarkresult">22.6</td><td class="benchmarkresult">25.2</td><td class="benchmarkresult">38.8</td><td class="benchmarkresult">69.0</td></tr>
|
||
</tbody></table></div><script>bench_sets['Build Type Name'] = {id:'bs7', tests:[
|
||
{name:'BuildTypeNameStr 0/0',data:[7.58,6.45,8.65,8.34,17.8,20.9]},
|
||
{name:'BuildTypeNameExp 0/0',data:[6.94,6.41,6.99,7.67,14.4,23.1]},
|
||
{name:'BuildTypeNameSim 0/0',data:[5.03,4.99,4.97,7.90,15.4,20.4]},
|
||
{name:'BuildTypeNameStr 10/10',data:[59.1,90.0,76.6,79.5,80.1,365]},
|
||
{name:'BuildTypeNameExp 10/10',data:[31.0,39.0,27.9,33.1,39.4,116]},
|
||
{name:'BuildTypeNameSim 10/10',data:[23.4,23.6,22.6,25.2,38.8,69.0]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs8"><h4><a id="bs54035654251116789780" href="#bs54035654251116789780">#</a> Replace string by copy</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L646">Concat with replace str</a><span class="tooltiptext code">std::string make_str_str(std::string_view from, std::string_view pattern, std::string_view repl) {
|
||
auto str_replace = [](std::string_view from, std::string_view pattern, std::string_view repl) {
|
||
std::string result;
|
||
for (size_t offset = 0; ;) {
|
||
size_t pos = from.find(pattern, offset);
|
||
if (pos == std::string::npos) {
|
||
result += from.substr(offset);
|
||
break;
|
||
}
|
||
result += from.substr(offset, pos - offset);
|
||
result += repl;
|
||
offset = pos + pattern.length();
|
||
}
|
||
return result;
|
||
};
|
||
return "<" + str_replace(from, pattern, repl) + ">";
|
||
}</span></span></td><td></td><td class="benchmarkresult">210</td><td class="benchmarkresult">243</td><td class="benchmarkresult">236</td><td class="benchmarkresult">315</td><td class="benchmarkresult">352</td><td class="benchmarkresult">500</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L664">Concat with replace exp</a><span class="tooltiptext code">std::string make_str_exp(std::string_view from, std::string_view pattern, std::string_view repl) {
|
||
return "<" + e_repl(from, pattern, repl) + ">";
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">В simstr строковое выражение для замены подстрок
|
||
есть "из коробки".
|
||
simstr has a string expression for replacing substrings out of the box.</span></span></td><td class="benchmarkresult">154</td><td class="benchmarkresult">151</td><td class="benchmarkresult">135</td><td class="benchmarkresult">220</td><td class="benchmarkresult">222</td><td class="benchmarkresult">235</td></tr>
|
||
</tbody></table></div><script>bench_sets['Replace string by copy'] = {id:'bs8', tests:[
|
||
{name:'Concat with replace str',data:[210,243,236,315,352,500]},
|
||
{name:'Concat with replace exp',data:[154,151,135,220,222,235]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs9"><h4><a id="bs77666948964429305550" href="#bs77666948964429305550">#</a> Create Empty Str</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L698">std::string e;</a><span class="tooltiptext code">template<typename T>
|
||
void CreateEmpty(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
T empty_string;
|
||
benchmark::DoNotOptimize(empty_string);
|
||
}
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">Пустые строки, ничего необычного.
|
||
Empty lines, nothing unusual.</span></span></td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">0.758</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">2.58</td><td class="benchmarkresult">2.15</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L698">std::string_view e;</a><span class="tooltiptext code">template<typename T>
|
||
void CreateEmpty(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
T empty_string;
|
||
benchmark::DoNotOptimize(empty_string);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">0.377</td><td class="benchmarkresult">0.380</td><td class="benchmarkresult">0.754</td><td class="benchmarkresult">0.369</td><td class="benchmarkresult">1.84</td><td class="benchmarkresult">0.740</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L698">ssa e;</a><span class="tooltiptext code">template<typename T>
|
||
void CreateEmpty(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
T empty_string;
|
||
benchmark::DoNotOptimize(empty_string);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">0.372</td><td class="benchmarkresult">0.375</td><td class="benchmarkresult">0.187</td><td class="benchmarkresult">0.362</td><td class="benchmarkresult">1.86</td><td class="benchmarkresult">0.378</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L698">stringa e;</a><span class="tooltiptext code">template<typename T>
|
||
void CreateEmpty(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
T empty_string;
|
||
benchmark::DoNotOptimize(empty_string);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">0.763</td><td class="benchmarkresult">0.754</td><td class="benchmarkresult">0.753</td><td class="benchmarkresult">0.745</td><td class="benchmarkresult">2.22</td><td class="benchmarkresult">2.15</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L698">lstringa<20> e;</a><span class="tooltiptext code">template<typename T>
|
||
void CreateEmpty(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
T empty_string;
|
||
benchmark::DoNotOptimize(empty_string);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.10</td><td class="benchmarkresult">2.55</td><td class="benchmarkresult">2.20</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L698">lstringa<40> e;</a><span class="tooltiptext code">template<typename T>
|
||
void CreateEmpty(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
T empty_string;
|
||
benchmark::DoNotOptimize(empty_string);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.11</td><td class="benchmarkresult">2.57</td><td class="benchmarkresult">2.20</td></tr>
|
||
</tbody></table></div><script>bench_sets['Create Empty Str'] = {id:'bs9', tests:[
|
||
{name:'std::string e;',data:[1.13,0.758,1.13,1.12,2.58,2.15]},
|
||
{name:'std::string_view e;',data:[0.377,0.380,0.754,0.369,1.84,0.740]},
|
||
{name:'ssa e;',data:[0.372,0.375,0.187,0.362,1.86,0.378]},
|
||
{name:'stringa e;',data:[0.763,0.754,0.753,0.745,2.22,2.15]},
|
||
{name:'lstringa<20> e;',data:[1.14,1.13,1.14,1.10,2.55,2.20]},
|
||
{name:'lstringa<40> e;',data:[1.14,1.14,1.15,1.11,2.57,2.20]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs10"><h4><a id="bs181001525395597238060" href="#bs181001525395597238060">#</a> Create Str from short literal (9 symbols)</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L713">std::string e = "Test text";</a><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,
|
||
время тратится только на копирование 10 байтов.
|
||
The short literal is placed in the internal std::string buffer;
|
||
time is spent only copying 10 bytes.</span></span></td><td class="benchmarkresult">1.87</td><td class="benchmarkresult">1.51</td><td class="benchmarkresult">1.89</td><td class="benchmarkresult">1.84</td><td class="benchmarkresult">2.57</td><td class="benchmarkresult">2.47</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L713">std::string_view e = "Test text";</a><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 - по сути одно и то же:
|
||
указатель на текст и его длина.
|
||
Both string_view and ssa are essentially the same thing:
|
||
a pointer to text and its length.</span></span></td><td class="benchmarkresult">0.761</td><td class="benchmarkresult">0.767</td><td class="benchmarkresult">0.754</td><td class="benchmarkresult">0.741</td><td class="benchmarkresult">1.84</td><td class="benchmarkresult">1.12</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L713">ssa e = "Test text";</a><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></td><td class="benchmarkresult">0.382</td><td class="benchmarkresult">0.381</td><td class="benchmarkresult">0.757</td><td class="benchmarkresult">0.369</td><td class="benchmarkresult">1.84</td><td class="benchmarkresult">0.744</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L713">stringa e = "Test text";</a><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 при инициализации константным литералом так же
|
||
сохраняет только указатель на текст и его длину.
|
||
When initialized with a constant literal, stringa also stores
|
||
only a pointer to the text and its length.</span></span></td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.11</td><td class="benchmarkresult">2.57</td><td class="benchmarkresult">2.19</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L713">lstringa<20> e = "Test text";</a><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">Внутреннего буфера хватает для размещения символов,
|
||
время уходит только на копирование байтов.
|
||
The internal buffer is sufficient to accommodate characters;
|
||
time is spent only on copying bytes.</span></span></td><td class="benchmarkresult">1.90</td><td class="benchmarkresult">1.89</td><td class="benchmarkresult">1.92</td><td class="benchmarkresult">1.84</td><td class="benchmarkresult">2.60</td><td class="benchmarkresult">2.63</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L713">lstringa<40> e = "Test text";</a><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></td><td class="benchmarkresult">1.88</td><td class="benchmarkresult">1.86</td><td class="benchmarkresult">1.90</td><td class="benchmarkresult">1.85</td><td class="benchmarkresult">2.58</td><td class="benchmarkresult">2.61</td></tr>
|
||
</tbody></table></div><script>bench_sets['Create Str from short literal (9 symbols)'] = {id:'bs10', tests:[
|
||
{name:'std::string e = "Test text";',data:[1.87,1.51,1.89,1.84,2.57,2.47]},
|
||
{name:'std::string_view e = "Test text";',data:[0.761,0.767,0.754,0.741,1.84,1.12]},
|
||
{name:'ssa e = "Test text";',data:[0.382,0.381,0.757,0.369,1.84,0.744]},
|
||
{name:'stringa e = "Test text";',data:[1.15,1.13,1.13,1.11,2.57,2.19]},
|
||
{name:'lstringa<20> e = "Test text";',data:[1.90,1.89,1.92,1.84,2.60,2.63]},
|
||
{name:'lstringa<40> e = "Test text";',data:[1.88,1.86,1.90,1.85,2.58,2.61]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs11"><h4><a id="bs132333183298742730280" href="#bs132333183298742730280">#</a> Create Str from long literal (30 symbols)</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L728">std::string e = "123456789012345678901234567890";</a><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-и байтов.
|
||
Но как же отстает аллокация под Windows от Linux'а, 20 vs 70 ns...
|
||
Here, the literal doesn't fit into the internal buffer,
|
||
and 30 bytes are allocated and copied.
|
||
But how much slower is allocation under Windows than under Linux, 20 ns vs. 70 ns...</span></span></td><td class="benchmarkresult">19.5</td><td class="benchmarkresult">19.3</td><td class="benchmarkresult">19.7</td><td class="benchmarkresult">73.9</td><td class="benchmarkresult">79.3</td><td class="benchmarkresult">21.8</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L728">std::string_view e = "123456789012345678901234567890";</a><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 по прежнему ничего не делают, кроме
|
||
запоминания указателя на текст и его размера.
|
||
string_view and ssa still do nothing except
|
||
remember the pointer to the text and its size.</span></span></td><td class="benchmarkresult">0.763</td><td class="benchmarkresult">0.745</td><td class="benchmarkresult">0.751</td><td class="benchmarkresult">0.736</td><td class="benchmarkresult">1.86</td><td class="benchmarkresult">1.10</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L728">ssa e = "123456789012345678901234567890";</a><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></td><td class="benchmarkresult">0.375</td><td class="benchmarkresult">0.374</td><td class="benchmarkresult">0.761</td><td class="benchmarkresult">0.369</td><td class="benchmarkresult">1.86</td><td class="benchmarkresult">0.741</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L728">stringa e = "123456789012345678901234567890";</a><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">stringa на константных литералах не отстает!
|
||
stringa doesn't lag behind on constant literals!</span></span></td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.11</td><td class="benchmarkresult">2.24</td><td class="benchmarkresult">2.22</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L728">lstringa<20> e = "123456789012345678901234567890";</a><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 символов,
|
||
Очевидно, что для 30-и символов уже нужна аллокация.
|
||
Obviously, 30 characters already require allocation.</span></span></td><td class="benchmarkresult">18.0</td><td class="benchmarkresult">18.9</td><td class="benchmarkresult">18.3</td><td class="benchmarkresult">73.1</td><td class="benchmarkresult">72.7</td><td class="benchmarkresult">22.0</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L728">lstringa<40> e = "123456789012345678901234567890";</a><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 символов, так что просто
|
||
копируется 30 байтов.
|
||
And lstringa<40> can hold up to 47 characters, so 30
|
||
bytes are simply copied.</span></span></td><td class="benchmarkresult">2.68</td><td class="benchmarkresult">1.89</td><td class="benchmarkresult">1.91</td><td class="benchmarkresult">2.56</td><td class="benchmarkresult">3.32</td><td class="benchmarkresult">2.98</td></tr>
|
||
</tbody></table></div><script>bench_sets['Create Str from long literal (30 symbols)'] = {id:'bs11', tests:[
|
||
{name:'std::string e = "123456789012345678901234567890";',data:[19.5,19.3,19.7,73.9,79.3,21.8]},
|
||
{name:'std::string_view e = "123456789012345678901234567890";',data:[0.763,0.745,0.751,0.736,1.86,1.10]},
|
||
{name:'ssa e = "123456789012345678901234567890";',data:[0.375,0.374,0.761,0.369,1.86,0.741]},
|
||
{name:'stringa e = "123456789012345678901234567890";',data:[1.14,1.12,1.13,1.11,2.24,2.22]},
|
||
{name:'lstringa<20> e = "123456789012345678901234567890";',data:[18.0,18.9,18.3,73.1,72.7,22.0]},
|
||
{name:'lstringa<40> e = "123456789012345678901234567890";',data:[2.68,1.89,1.91,2.56,3.32,2.98]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs12"><h4><a id="bs6234433963744178700" href="#bs6234433963744178700">#</a> Create copy of Str with 9 symbols</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L743">std::string e = "Test text"; auto c{e};</a><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">Строка в пределах SSO, так что просто копирует байты.
|
||
The string is within the SSO, so it just copies the bytes.</span></span></td><td class="benchmarkresult">5.77</td><td class="benchmarkresult">1.18</td><td class="benchmarkresult">5.03</td><td class="benchmarkresult">1.84</td><td class="benchmarkresult">5.40</td><td class="benchmarkresult">3.72</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L743">std::string_view e = "Test text"; auto c{e};</a><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></td><td class="benchmarkresult">0.388</td><td class="benchmarkresult">0.377</td><td class="benchmarkresult">0.388</td><td class="benchmarkresult">0.373</td><td class="benchmarkresult">2.95</td><td class="benchmarkresult">1.10</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L743">ssa e = "Test text"; auto c{e};</a><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 не владеют строкой, копируется
|
||
только информация о строке.
|
||
ssa and string_view don't own the string; only the
|
||
string information is copied.</span></span></td><td class="benchmarkresult">0.380</td><td class="benchmarkresult">0.378</td><td class="benchmarkresult">0.388</td><td class="benchmarkresult">0.380</td><td class="benchmarkresult">2.95</td><td class="benchmarkresult">1.11</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L743">stringa e = "Test text"; auto c{e};</a><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 происходит быстро,
|
||
особенно если она инициализирована литералом.
|
||
Copying a stringa is fast,
|
||
especially if it is initialized with a literal.</span></span></td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.10</td><td class="benchmarkresult">4.12</td><td class="benchmarkresult">2.53</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L743">lstringa<20> e = "Test text"; auto c{e};</a><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">В обоих случаях хватает внутреннего буфера.
|
||
In both cases, the internal buffer is sufficient.</span></span></td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">4.78</td><td class="benchmarkresult">4.17</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L743">lstringa<40> e = "Test text"; auto c{e};</a><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">Только копируются байты.
|
||
Only bytes are copied.</span></span></td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.85</td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.11</td><td class="benchmarkresult">5.49</td><td class="benchmarkresult">4.49</td></tr>
|
||
</tbody></table></div><script>bench_sets['Create copy of Str with 9 symbols'] = {id:'bs12', tests:[
|
||
{name:'std::string e = "Test text"; auto c{e};',data:[5.77,1.18,5.03,1.84,5.40,3.72]},
|
||
{name:'std::string_view e = "Test text"; auto c{e};',data:[0.388,0.377,0.388,0.373,2.95,1.10]},
|
||
{name:'ssa e = "Test text"; auto c{e};',data:[0.380,0.378,0.388,0.380,2.95,1.11]},
|
||
{name:'stringa e = "Test text"; auto c{e};',data:[1.12,1.13,1.13,1.10,4.12,2.53]},
|
||
{name:'lstringa<20> e = "Test text"; auto c{e};',data:[1.14,1.12,1.15,1.12,4.78,4.17]},
|
||
{name:'lstringa<40> e = "Test text"; auto c{e};',data:[1.15,1.85,1.15,1.11,5.49,4.49]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs13"><h4><a id="bs76384575499199461500" href="#bs76384575499199461500">#</a> Create copy of Str with 30 symbols</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L760">std::string e = "123456789012345678901234567890"; auto c{e};</a><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">Копирования длинной строки вызывает аллокацию,
|
||
SSO уже не хватает. И снова как же отстаёт аллокация под Windows...
|
||
Copying a long string causes allocations,
|
||
SSO is no longer sufficient. And again, how allocation lags under Windows...</span></span></td><td class="benchmarkresult">20.2</td><td class="benchmarkresult">24.9</td><td class="benchmarkresult">23.2</td><td class="benchmarkresult">78.0</td><td class="benchmarkresult">78.8</td><td class="benchmarkresult">46.5</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L760">std::string_view e = "123456789012345678901234567890"; auto c{e};</a><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></td><td class="benchmarkresult">0.758</td><td class="benchmarkresult">0.757</td><td class="benchmarkresult">0.759</td><td class="benchmarkresult">0.734</td><td class="benchmarkresult">1.50</td><td class="benchmarkresult">1.11</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L760">ssa e = "123456789012345678901234567890"; auto c{e};</a><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></td><td class="benchmarkresult">0.374</td><td class="benchmarkresult">0.381</td><td class="benchmarkresult">0.758</td><td class="benchmarkresult">0.377</td><td class="benchmarkresult">1.47</td><td class="benchmarkresult">0.750</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L760">stringa e = "123456789012345678901234567890"; auto c{e};</a><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 копирование литерала не зависит от его длины,
|
||
сравни с предыдущим бенчмарком.
|
||
But with stringa, literal copying doesn't depend on its length,
|
||
compare with the previous benchmark.</span></span></td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">6.85</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">2.98</td><td class="benchmarkresult">2.21</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L760">lstringa<20> e = "123456789012345678901234567890"; auto c{e};</a><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">Не влезает, аллокация.
|
||
Doesn't fit, allocation.</span></span></td><td class="benchmarkresult">19.1</td><td class="benchmarkresult">18.0</td><td class="benchmarkresult">17.7</td><td class="benchmarkresult">72.6</td><td class="benchmarkresult">82.9</td><td class="benchmarkresult">21.2</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L760">lstringa<40> e = "123456789012345678901234567890"; auto c{e};</a><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">Уложили во внутренний буфер.
|
||
Placed in the internal buffer.</span></span></td><td class="benchmarkresult">4.98</td><td class="benchmarkresult">5.53</td><td class="benchmarkresult">4.18</td><td class="benchmarkresult">5.42</td><td class="benchmarkresult">7.41</td><td class="benchmarkresult">15.8</td></tr>
|
||
</tbody></table></div><script>bench_sets['Create copy of Str with 30 symbols'] = {id:'bs13', tests:[
|
||
{name:'std::string e = "123456789012345678901234567890"; auto c{e};',data:[20.2,24.9,23.2,78.0,78.8,46.5]},
|
||
{name:'std::string_view e = "123456789012345678901234567890"; auto c{e};',data:[0.758,0.757,0.759,0.734,1.50,1.11]},
|
||
{name:'ssa e = "123456789012345678901234567890"; auto c{e};',data:[0.374,0.381,0.758,0.377,1.47,0.750]},
|
||
{name:'stringa e = "123456789012345678901234567890"; auto c{e};',data:[1.14,1.14,6.85,1.12,2.98,2.21]},
|
||
{name:'lstringa<20> e = "123456789012345678901234567890"; auto c{e};',data:[19.1,18.0,17.7,72.6,82.9,21.2]},
|
||
{name:'lstringa<40> e = "123456789012345678901234567890"; auto c{e};',data:[4.98,5.53,4.18,5.42,7.41,15.8]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs14"><h4><a id="bs21623892135774528620" href="#bs21623892135774528620">#</a> Find 9 symbols text in end of 99 symbols text</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">sz::string::find;</a><span class="tooltiptext code">template<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">stringzilla более заточена на поиск больших строк в больших строках.
|
||
stringzilla is more focused on searching large strings within large strings.</span></span></td><td class="benchmarkresult">95.9</td><td class="benchmarkresult">96.5</td><td class="benchmarkresult">87.9</td><td class="benchmarkresult">94.8</td><td class="benchmarkresult">117</td><td class="benchmarkresult">125</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">std::string::find;</a><span class="tooltiptext code">template<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">Здесь "победила дружба", у всех типов по колонке примерно одинаково.
|
||
Однако, Windows и Linux явно в разных весовых категориях.
|
||
Here, "friendship wins," with all types scoring roughly equally.
|
||
However, Windows and Linux are clearly in different weight classes.</span></span></td><td class="benchmarkresult">7.34</td><td class="benchmarkresult">7.76</td><td class="benchmarkresult">6.95</td><td class="benchmarkresult">40.2</td><td class="benchmarkresult">40.3</td><td class="benchmarkresult">40.8</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">std::string_view::find;</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">7.81</td><td class="benchmarkresult">7.82</td><td class="benchmarkresult">7.39</td><td class="benchmarkresult">39.3</td><td class="benchmarkresult">39.8</td><td class="benchmarkresult">41.2</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">ssa::find;</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">7.37</td><td class="benchmarkresult">7.82</td><td class="benchmarkresult">6.87</td><td class="benchmarkresult">18.7</td><td class="benchmarkresult">21.9</td><td class="benchmarkresult">40.6</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">stringa::find;</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">8.14</td><td class="benchmarkresult">8.60</td><td class="benchmarkresult">7.21</td><td class="benchmarkresult">19.6</td><td class="benchmarkresult">29.4</td><td class="benchmarkresult">41.2</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">lstringa<20>::find;</a><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></td><td class="benchmarkresult">6.94</td><td class="benchmarkresult">6.98</td><td class="benchmarkresult">6.52</td><td class="benchmarkresult">18.0</td><td class="benchmarkresult">24.4</td><td class="benchmarkresult">39.8</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L777">lstringa<40>::find;</a><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></td><td class="benchmarkresult">6.93</td><td class="benchmarkresult">7.01</td><td class="benchmarkresult">6.49</td><td class="benchmarkresult">18.5</td><td class="benchmarkresult">23.1</td><td class="benchmarkresult">39.7</td></tr>
|
||
</tbody></table></div><script>bench_sets['Find 9 symbols text in end of 99 symbols text'] = {id:'bs14', tests:[
|
||
{name:'sz::string::find;',data:[95.9,96.5,87.9,94.8,117,125]},
|
||
{name:'std::string::find;',data:[7.34,7.76,6.95,40.2,40.3,40.8]},
|
||
{name:'std::string_view::find;',data:[7.81,7.82,7.39,39.3,39.8,41.2]},
|
||
{name:'ssa::find;',data:[7.37,7.82,6.87,18.7,21.9,40.6]},
|
||
{name:'stringa::find;',data:[8.14,8.60,7.21,19.6,29.4,41.2]},
|
||
{name:'lstringa<20>::find;',data:[6.94,6.98,6.52,18.0,24.4,39.8]},
|
||
{name:'lstringa<40>::find;',data:[6.93,7.01,6.49,18.5,23.1,39.7]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs15"><h4><a id="bs170792414351801782640" href="#bs170792414351801782640">#</a> Copy not literal Str with N symbols</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/15</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">5.78</td><td class="benchmarkresult">1.18</td><td class="benchmarkresult">5.01</td><td class="benchmarkresult">1.83</td><td class="benchmarkresult">5.18</td><td class="benchmarkresult">52.3</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/16</a><span class="tooltiptext code">template<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-битный, и там размер
|
||
SSO у std::string меньше, 10 символов + 0.
|
||
The jump where SSO ends and allocation begins is clearly visible.
|
||
Note that WASM is 32-bit, and the size of the SSO for std::string is
|
||
smaller, as far as I remember: 11 characters + 0.</span></span></td><td class="benchmarkresult">24.5</td><td class="benchmarkresult">1.16</td><td class="benchmarkresult">29.4</td><td class="benchmarkresult">78.7</td><td class="benchmarkresult">83.5</td><td class="benchmarkresult">53.0</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/23</a><span class="tooltiptext code">template<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">Дальше просто добавляется время на копирование байтов.
|
||
Then the time for copying bytes is simply added.</span></span></td><td class="benchmarkresult">28.5</td><td class="benchmarkresult">25.8</td><td class="benchmarkresult">28.9</td><td class="benchmarkresult">79.1</td><td class="benchmarkresult">82.0</td><td class="benchmarkresult">52.5</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/24</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">23.3</td><td class="benchmarkresult">24.8</td><td class="benchmarkresult">22.3</td><td class="benchmarkresult">80.3</td><td class="benchmarkresult">83.5</td><td class="benchmarkresult">51.6</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/32</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">23.2</td><td class="benchmarkresult">24.7</td><td class="benchmarkresult">21.5</td><td class="benchmarkresult">79.6</td><td class="benchmarkresult">89.4</td><td class="benchmarkresult">53.9</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/64</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">23.3</td><td class="benchmarkresult">26.2</td><td class="benchmarkresult">24.6</td><td class="benchmarkresult">80.7</td><td class="benchmarkresult">90.6</td><td class="benchmarkresult">54.4</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/128</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">24.9</td><td class="benchmarkresult">26.8</td><td class="benchmarkresult">24.2</td><td class="benchmarkresult">84.2</td><td class="benchmarkresult">90.0</td><td class="benchmarkresult">59.7</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/256</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">26.0</td><td class="benchmarkresult">27.5</td><td class="benchmarkresult">25.7</td><td class="benchmarkresult">87.3</td><td class="benchmarkresult">91.8</td><td class="benchmarkresult">73.8</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/512</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">29.4</td><td class="benchmarkresult">31.6</td><td class="benchmarkresult">28.5</td><td class="benchmarkresult">87.3</td><td class="benchmarkresult">96.2</td><td class="benchmarkresult">81.2</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/1024</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">47.7</td><td class="benchmarkresult">38.4</td><td class="benchmarkresult">33.4</td><td class="benchmarkresult">97.6</td><td class="benchmarkresult">102</td><td class="benchmarkresult">93.3</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/2048</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">125</td><td class="benchmarkresult">86.0</td><td class="benchmarkresult">122</td><td class="benchmarkresult">132</td><td class="benchmarkresult">132</td><td class="benchmarkresult">109</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">std::string copy{str_with_len_N};/4096</a><span class="tooltiptext code">template<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">Чем длиннее строка, тем дольше создаётся копия.
|
||
The longer the string, the longer it takes to create a copy.</span></span></td><td class="benchmarkresult">152</td><td class="benchmarkresult">117</td><td class="benchmarkresult">157</td><td class="benchmarkresult">180</td><td class="benchmarkresult">184</td><td class="benchmarkresult">165</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/15</a><span class="tooltiptext code">template<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 инициализируется не литералом,
|
||
а значит, должна сама хранить символы.
|
||
Here, stringa is not initialized with a literal,
|
||
meaning it must store characters itself.</span></span></td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.09</td><td class="benchmarkresult">4.04</td><td class="benchmarkresult">2.46</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/16</a><span class="tooltiptext code">template<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 символов. Кроме того,
|
||
собиралось без поддержки потоков, поэтому атомарный
|
||
инкремент заменён на обычный, судя по времени.
|
||
Under WASM, stringa has a 15-character SSO. Furthermore,
|
||
it was built without thread support, so the atomic
|
||
increment was replaced with a regular one, judging by the time.</span></span></td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.08</td><td class="benchmarkresult">4.07</td><td class="benchmarkresult">4.57</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/23</a><span class="tooltiptext code">template<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
|
||
копируются быстрее, чем 15 в std::string.
|
||
SSO in stringa is up to 23 characters, and even 23
|
||
copies faster than 15 in std::string.</span></span></td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.09</td><td class="benchmarkresult">4.09</td><td class="benchmarkresult">4.54</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/24</a><span class="tooltiptext code">template<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 буфер.
|
||
Добавляется время на атомарный инкремент счётчика.
|
||
That's it, we're not using SSO, so we're using a shared buffer.
|
||
Time is added for the atomic counter increment.</span></span></td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.1</td><td class="benchmarkresult">18.8</td><td class="benchmarkresult">4.55</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/32</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">16.3</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.1</td><td class="benchmarkresult">18.6</td><td class="benchmarkresult">4.57</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/64</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">16.3</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.0</td><td class="benchmarkresult">18.6</td><td class="benchmarkresult">4.56</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/128</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.1</td><td class="benchmarkresult">18.6</td><td class="benchmarkresult">4.55</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/256</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.6</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.1</td><td class="benchmarkresult">18.7</td><td class="benchmarkresult">4.57</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/512</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.6</td><td class="benchmarkresult">16.3</td><td class="benchmarkresult">16.0</td><td class="benchmarkresult">19.1</td><td class="benchmarkresult">4.60</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/1024</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">16.3</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.1</td><td class="benchmarkresult">18.7</td><td class="benchmarkresult">4.57</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/2048</a><span class="tooltiptext code">template<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></td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.0</td><td class="benchmarkresult">18.7</td><td class="benchmarkresult">4.56</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">stringa copy{str_with_len_N};/4096</a><span class="tooltiptext code">template<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">И как видно, кроме инкремента нет накладных расходов,
|
||
время копирования не зависит от длины строки.
|
||
And as you can see, there are no overhead costs other than the
|
||
increment; copying time does not depend on the string length.</span></span></td><td class="benchmarkresult">16.4</td><td class="benchmarkresult">16.7</td><td class="benchmarkresult">16.5</td><td class="benchmarkresult">16.1</td><td class="benchmarkresult">18.7</td><td class="benchmarkresult">4.57</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<16> copy{str_with_len_N};/15</a><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 символов.
|
||
А в WASM 32-битная архитектура, SSO до 19 символов.
|
||
lstringa<16> uses SSO up to 23 characters.
|
||
WASM has a 32-bit architecture, so SSO is up to 19 characters.</span></span></td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.12</td><td class="benchmarkresult">4.06</td><td class="benchmarkresult">4.14</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<16> copy{str_with_len_N};/16</a><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></td><td class="benchmarkresult">5.10</td><td class="benchmarkresult">5.35</td><td class="benchmarkresult">4.89</td><td class="benchmarkresult">4.56</td><td class="benchmarkresult">8.48</td><td class="benchmarkresult">16.9</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<16> copy{str_with_len_N};/23</a><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></td><td class="benchmarkresult">5.16</td><td class="benchmarkresult">5.31</td><td class="benchmarkresult">4.91</td><td class="benchmarkresult">4.49</td><td class="benchmarkresult">8.54</td><td class="benchmarkresult">36.0</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<16> copy{str_with_len_N};/24</a><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">И после начинает вести себя при копировании, как std::string.
|
||
And then it starts to behave like std::string when copied.</span></span></td><td class="benchmarkresult">21.9</td><td class="benchmarkresult">21.8</td><td class="benchmarkresult">22.4</td><td class="benchmarkresult">76.6</td><td class="benchmarkresult">81.2</td><td class="benchmarkresult">37.0</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<16> copy{str_with_len_N};/32</a><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></td><td class="benchmarkresult">22.1</td><td class="benchmarkresult">21.9</td><td class="benchmarkresult">22.5</td><td class="benchmarkresult">77.3</td><td class="benchmarkresult">84.1</td><td class="benchmarkresult">38.0</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<16> copy{str_with_len_N};/64</a><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></td><td class="benchmarkresult">23.4</td><td class="benchmarkresult">23.1</td><td class="benchmarkresult">24.3</td><td class="benchmarkresult">79.3</td><td class="benchmarkresult">82.4</td><td class="benchmarkresult">38.3</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<16> copy{str_with_len_N};/128</a><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></td><td class="benchmarkresult">24.5</td><td class="benchmarkresult">25.7</td><td class="benchmarkresult">33.8</td><td class="benchmarkresult">82.6</td><td class="benchmarkresult">85.6</td><td class="benchmarkresult">38.8</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<16> copy{str_with_len_N};/256</a><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></td><td class="benchmarkresult">25.4</td><td class="benchmarkresult">24.8</td><td class="benchmarkresult">25.9</td><td class="benchmarkresult">83.7</td><td class="benchmarkresult">87.1</td><td class="benchmarkresult">62.4</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<16> copy{str_with_len_N};/512</a><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></td><td class="benchmarkresult">28.6</td><td class="benchmarkresult">27.7</td><td class="benchmarkresult">34.8</td><td class="benchmarkresult">88.5</td><td class="benchmarkresult">90.7</td><td class="benchmarkresult">66.7</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<16> copy{str_with_len_N};/1024</a><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></td><td class="benchmarkresult">98.9</td><td class="benchmarkresult">78.4</td><td class="benchmarkresult">99.7</td><td class="benchmarkresult">93.9</td><td class="benchmarkresult">101</td><td class="benchmarkresult">78.8</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<16> copy{str_with_len_N};/2048</a><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></td><td class="benchmarkresult">103</td><td class="benchmarkresult">73.4</td><td class="benchmarkresult">110</td><td class="benchmarkresult">125</td><td class="benchmarkresult">135</td><td class="benchmarkresult">94.8</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<16> copy{str_with_len_N};/4096</a><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></td><td class="benchmarkresult">122</td><td class="benchmarkresult">88.6</td><td class="benchmarkresult">129</td><td class="benchmarkresult">190</td><td class="benchmarkresult">196</td><td class="benchmarkresult">146</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<512> copy{str_with_len_N};/15</a><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></td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.13</td><td class="benchmarkresult">1.15</td><td class="benchmarkresult">1.14</td><td class="benchmarkresult">4.46</td><td class="benchmarkresult">4.06</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<512> copy{str_with_len_N};/16</a><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></td><td class="benchmarkresult">5.00</td><td class="benchmarkresult">4.98</td><td class="benchmarkresult">4.22</td><td class="benchmarkresult">6.12</td><td class="benchmarkresult">8.96</td><td class="benchmarkresult">15.1</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<512> copy{str_with_len_N};/23</a><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></td><td class="benchmarkresult">4.92</td><td class="benchmarkresult">5.01</td><td class="benchmarkresult">4.24</td><td class="benchmarkresult">5.29</td><td class="benchmarkresult">8.92</td><td class="benchmarkresult">15.1</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<512> copy{str_with_len_N};/24</a><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></td><td class="benchmarkresult">29.6</td><td class="benchmarkresult">4.59</td><td class="benchmarkresult">4.26</td><td class="benchmarkresult">5.27</td><td class="benchmarkresult">9.07</td><td class="benchmarkresult">15.2</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<512> copy{str_with_len_N};/32</a><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></td><td class="benchmarkresult">29.6</td><td class="benchmarkresult">4.64</td><td class="benchmarkresult">4.20</td><td class="benchmarkresult">8.14</td><td class="benchmarkresult">12.6</td><td class="benchmarkresult">16.9</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<512> copy{str_with_len_N};/64</a><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></td><td class="benchmarkresult">30.2</td><td class="benchmarkresult">6.06</td><td class="benchmarkresult">5.67</td><td class="benchmarkresult">8.48</td><td class="benchmarkresult">12.5</td><td class="benchmarkresult">17.9</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<512> copy{str_with_len_N};/128</a><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></td><td class="benchmarkresult">30.5</td><td class="benchmarkresult">6.63</td><td class="benchmarkresult">6.29</td><td class="benchmarkresult">8.58</td><td class="benchmarkresult">12.9</td><td class="benchmarkresult">18.2</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<512> copy{str_with_len_N};/256</a><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></td><td class="benchmarkresult">21.7</td><td class="benchmarkresult">17.3</td><td class="benchmarkresult">7.98</td><td class="benchmarkresult">9.69</td><td class="benchmarkresult">14.0</td><td class="benchmarkresult">20.8</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<512> copy{str_with_len_N};/512</a><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 символов копируются быстрее, чем
|
||
одна аллокация или атомарный инкремент.
|
||
Even 512 characters are copied faster than a single
|
||
allocation or atomic increment.</span></span></td><td class="benchmarkresult">24.7</td><td class="benchmarkresult">10.6</td><td class="benchmarkresult">10.2</td><td class="benchmarkresult">11.4</td><td class="benchmarkresult">15.7</td><td class="benchmarkresult">24.0</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<512> copy{str_with_len_N};/1024</a><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">А дальше уже как у всех.
|
||
And then it's like everyone else.</span></span></td><td class="benchmarkresult">96.9</td><td class="benchmarkresult">52.1</td><td class="benchmarkresult">96.5</td><td class="benchmarkresult">98.3</td><td class="benchmarkresult">95.0</td><td class="benchmarkresult">78.6</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<512> copy{str_with_len_N};/2048</a><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></td><td class="benchmarkresult">106</td><td class="benchmarkresult">73.6</td><td class="benchmarkresult">103</td><td class="benchmarkresult">130</td><td class="benchmarkresult">128</td><td class="benchmarkresult">95.8</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L801">lstringa<512> copy{str_with_len_N};/4096</a><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></td><td class="benchmarkresult">123</td><td class="benchmarkresult">90.1</td><td class="benchmarkresult">126</td><td class="benchmarkresult">188</td><td class="benchmarkresult">193</td><td class="benchmarkresult">146</td></tr>
|
||
</tbody></table></div><script>bench_sets['Copy not literal Str with N symbols'] = {id:'bs15', tests:[
|
||
{name:'std::string copy{str_with_len_N};/15',data:[5.78,1.18,5.01,1.83,5.18,52.3]},
|
||
{name:'std::string copy{str_with_len_N};/16',data:[24.5,1.16,29.4,78.7,83.5,53.0]},
|
||
{name:'std::string copy{str_with_len_N};/23',data:[28.5,25.8,28.9,79.1,82.0,52.5]},
|
||
{name:'std::string copy{str_with_len_N};/24',data:[23.3,24.8,22.3,80.3,83.5,51.6]},
|
||
{name:'std::string copy{str_with_len_N};/32',data:[23.2,24.7,21.5,79.6,89.4,53.9]},
|
||
{name:'std::string copy{str_with_len_N};/64',data:[23.3,26.2,24.6,80.7,90.6,54.4]},
|
||
{name:'std::string copy{str_with_len_N};/128',data:[24.9,26.8,24.2,84.2,90.0,59.7]},
|
||
{name:'std::string copy{str_with_len_N};/256',data:[26.0,27.5,25.7,87.3,91.8,73.8]},
|
||
{name:'std::string copy{str_with_len_N};/512',data:[29.4,31.6,28.5,87.3,96.2,81.2]},
|
||
{name:'std::string copy{str_with_len_N};/1024',data:[47.7,38.4,33.4,97.6,102,93.3]},
|
||
{name:'std::string copy{str_with_len_N};/2048',data:[125,86.0,122,132,132,109]},
|
||
{name:'std::string copy{str_with_len_N};/4096',data:[152,117,157,180,184,165]},
|
||
{name:'stringa copy{str_with_len_N};/15',data:[1.12,1.13,1.13,1.09,4.04,2.46]},
|
||
{name:'stringa copy{str_with_len_N};/16',data:[1.13,1.13,1.15,1.08,4.07,4.57]},
|
||
{name:'stringa copy{str_with_len_N};/23',data:[1.12,1.13,1.13,1.09,4.09,4.54]},
|
||
{name:'stringa copy{str_with_len_N};/24',data:[16.4,16.5,16.4,16.1,18.8,4.55]},
|
||
{name:'stringa copy{str_with_len_N};/32',data:[16.3,16.5,16.4,16.1,18.6,4.57]},
|
||
{name:'stringa copy{str_with_len_N};/64',data:[16.3,16.5,16.5,16.0,18.6,4.56]},
|
||
{name:'stringa copy{str_with_len_N};/128',data:[16.4,16.5,16.4,16.1,18.6,4.55]},
|
||
{name:'stringa copy{str_with_len_N};/256',data:[16.4,16.6,16.5,16.1,18.7,4.57]},
|
||
{name:'stringa copy{str_with_len_N};/512',data:[16.4,16.6,16.3,16.0,19.1,4.60]},
|
||
{name:'stringa copy{str_with_len_N};/1024',data:[16.3,16.5,16.4,16.1,18.7,4.57]},
|
||
{name:'stringa copy{str_with_len_N};/2048',data:[16.4,16.5,16.4,16.0,18.7,4.56]},
|
||
{name:'stringa copy{str_with_len_N};/4096',data:[16.4,16.7,16.5,16.1,18.7,4.57]},
|
||
{name:'lstringa<16> copy{str_with_len_N};/15',data:[1.14,1.12,1.15,1.12,4.06,4.14]},
|
||
{name:'lstringa<16> copy{str_with_len_N};/16',data:[5.10,5.35,4.89,4.56,8.48,16.9]},
|
||
{name:'lstringa<16> copy{str_with_len_N};/23',data:[5.16,5.31,4.91,4.49,8.54,36.0]},
|
||
{name:'lstringa<16> copy{str_with_len_N};/24',data:[21.9,21.8,22.4,76.6,81.2,37.0]},
|
||
{name:'lstringa<16> copy{str_with_len_N};/32',data:[22.1,21.9,22.5,77.3,84.1,38.0]},
|
||
{name:'lstringa<16> copy{str_with_len_N};/64',data:[23.4,23.1,24.3,79.3,82.4,38.3]},
|
||
{name:'lstringa<16> copy{str_with_len_N};/128',data:[24.5,25.7,33.8,82.6,85.6,38.8]},
|
||
{name:'lstringa<16> copy{str_with_len_N};/256',data:[25.4,24.8,25.9,83.7,87.1,62.4]},
|
||
{name:'lstringa<16> copy{str_with_len_N};/512',data:[28.6,27.7,34.8,88.5,90.7,66.7]},
|
||
{name:'lstringa<16> copy{str_with_len_N};/1024',data:[98.9,78.4,99.7,93.9,101,78.8]},
|
||
{name:'lstringa<16> copy{str_with_len_N};/2048',data:[103,73.4,110,125,135,94.8]},
|
||
{name:'lstringa<16> copy{str_with_len_N};/4096',data:[122,88.6,129,190,196,146]},
|
||
{name:'lstringa<512> copy{str_with_len_N};/15',data:[1.13,1.13,1.15,1.14,4.46,4.06]},
|
||
{name:'lstringa<512> copy{str_with_len_N};/16',data:[5.00,4.98,4.22,6.12,8.96,15.1]},
|
||
{name:'lstringa<512> copy{str_with_len_N};/23',data:[4.92,5.01,4.24,5.29,8.92,15.1]},
|
||
{name:'lstringa<512> copy{str_with_len_N};/24',data:[29.6,4.59,4.26,5.27,9.07,15.2]},
|
||
{name:'lstringa<512> copy{str_with_len_N};/32',data:[29.6,4.64,4.20,8.14,12.6,16.9]},
|
||
{name:'lstringa<512> copy{str_with_len_N};/64',data:[30.2,6.06,5.67,8.48,12.5,17.9]},
|
||
{name:'lstringa<512> copy{str_with_len_N};/128',data:[30.5,6.63,6.29,8.58,12.9,18.2]},
|
||
{name:'lstringa<512> copy{str_with_len_N};/256',data:[21.7,17.3,7.98,9.69,14.0,20.8]},
|
||
{name:'lstringa<512> copy{str_with_len_N};/512',data:[24.7,10.6,10.2,11.4,15.7,24.0]},
|
||
{name:'lstringa<512> copy{str_with_len_N};/1024',data:[96.9,52.1,96.5,98.3,95.0,78.6]},
|
||
{name:'lstringa<512> copy{str_with_len_N};/2048',data:[106,73.6,103,130,128,95.8]},
|
||
{name:'lstringa<512> copy{str_with_len_N};/4096',data:[123,90.1,126,188,193,146]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs16"><h4><a id="bs94756718925776995960" href="#bs94756718925776995960">#</a> Convert to int '1234567'</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L816">std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);</a><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", но он к сожалению очень ограничен
|
||
по возможностям. Здесь я попытался произвести тесты, близкие по
|
||
логике к работе std::from_chars
|
||
In simstr, a string fragment is sufficient for conversion to a number;
|
||
there's no need for null termination. The closest analog to this behavior
|
||
is "std::from_chars," but unfortunately, it is very limited in its capabilities.
|
||
Here, I attempted to run tests that are similar in logic to std::from_chars.</span></span></td><td class="benchmarkresult">26.9</td><td class="benchmarkresult">27.4</td><td class="benchmarkresult">27.9</td><td class="benchmarkresult">31.4</td><td class="benchmarkresult">31.9</td><td class="benchmarkresult">91.7</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L855">std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);</a><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 требует точного указания основания счисления,
|
||
не допускает знаков плюс, пробелов, префиксов 0x и т.п.
|
||
from_chars requires an exact radix specification and does not allow plus
|
||
signs, spaces, 0x prefixes, etc.</span></span></td><td class="benchmarkresult">14.9</td><td class="benchmarkresult">17.5</td><td class="benchmarkresult">12.5</td><td class="benchmarkresult">12.6</td><td class="benchmarkresult">11.8</td><td class="benchmarkresult">0.739</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L883">stringa s = "123456789"; int res = s.to_int<int, true, 10, false></a><span class="tooltiptext code">template<typename T>
|
||
void ToIntSimStr10(benchmark::State& state, T t, int c) {
|
||
for (auto _: state) {
|
||
int res = t. template to_int<int, true, 10, false, false>().value;
|
||
#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 заданы такие же ограничения - проверять переполнение,
|
||
десятичная система, без лидирующих пробелов и знака плюс
|
||
Here, to_int has the same restrictions: check for overflow,
|
||
decimal system, no leading spaces, and no plus sign.</span></span></td><td class="benchmarkresult">9.36</td><td class="benchmarkresult">9.48</td><td class="benchmarkresult">16.8</td><td class="benchmarkresult">13.7</td><td class="benchmarkresult">16.8</td><td class="benchmarkresult">20.4</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L883">ssa s = "123456789"; int res = s.to_int<int, true, 10, false></a><span class="tooltiptext code">template<typename T>
|
||
void ToIntSimStr10(benchmark::State& state, T t, int c) {
|
||
for (auto _: state) {
|
||
int res = t. template to_int<int, true, 10, false, false>().value;
|
||
#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">9.52</td><td class="benchmarkresult">9.76</td><td class="benchmarkresult">7.54</td><td class="benchmarkresult">9.40</td><td class="benchmarkresult">15.6</td><td class="benchmarkresult">16.2</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L883">lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false></a><span class="tooltiptext code">template<typename T>
|
||
void ToIntSimStr10(benchmark::State& state, T t, int c) {
|
||
for (auto _: state) {
|
||
int res = t. template to_int<int, true, 10, false, false>().value;
|
||
#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">9.61</td><td class="benchmarkresult">9.51</td><td class="benchmarkresult">8.43</td><td class="benchmarkresult">13.4</td><td class="benchmarkresult">14.8</td><td class="benchmarkresult">16.1</td></tr>
|
||
</tbody></table></div><script>bench_sets['Convert to int \'1234567\''] = {id:'bs16', tests:[
|
||
{name:'std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);',data:[26.9,27.4,27.9,31.4,31.9,91.7]},
|
||
{name:'std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);',data:[14.9,17.5,12.5,12.6,11.8,0.739]},
|
||
{name:'stringa s = "123456789"; int res = s.to_int<int, true, 10, false>',data:[9.36,9.48,16.8,13.7,16.8,20.4]},
|
||
{name:'ssa s = "123456789"; int res = s.to_int<int, true, 10, false>',data:[9.52,9.76,7.54,9.40,15.6,16.2]},
|
||
{name:'lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>',data:[9.61,9.51,8.43,13.4,14.8,16.1]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs17"><h4><a id="bs182426078870126042750" href="#bs182426078870126042750">#</a> Convert to unsigned 'abcDef'</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L829">std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);</a><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);
|
||
}
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">Всё то же, только для 16ричной системы
|
||
Everything is the same, only for the hexadecimal system</span></span></td><td class="benchmarkresult">24.5</td><td class="benchmarkresult">24.4</td><td class="benchmarkresult">23.9</td><td class="benchmarkresult">33.6</td><td class="benchmarkresult">35.5</td><td class="benchmarkresult">67.2</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L869">std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">9.59</td><td class="benchmarkresult">22.0</td><td class="benchmarkresult">9.15</td><td class="benchmarkresult">8.50</td><td class="benchmarkresult">8.96</td><td class="benchmarkresult">18.3</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L898">stringa s = "abcDef"; int res = s.to_int<int, true, 16, false></a><span class="tooltiptext code">template<typename T>
|
||
void ToIntSimStr16(benchmark::State& state, T t, int c) {
|
||
for (auto _: state) {
|
||
int res = t. template to_int<int, true, 16, false, false>().value;
|
||
#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">8.04</td><td class="benchmarkresult">8.28</td><td class="benchmarkresult">16.2</td><td class="benchmarkresult">13.7</td><td class="benchmarkresult">14.5</td><td class="benchmarkresult">17.2</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L898">ssa s = "abcDef"; int res = s.to_int<int, true, 16, false></a><span class="tooltiptext code">template<typename T>
|
||
void ToIntSimStr16(benchmark::State& state, T t, int c) {
|
||
for (auto _: state) {
|
||
int res = t. template to_int<int, true, 16, false, false>().value;
|
||
#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">7.57</td><td class="benchmarkresult">7.65</td><td class="benchmarkresult">6.48</td><td class="benchmarkresult">7.50</td><td class="benchmarkresult">13.3</td><td class="benchmarkresult">16.7</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L898">lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false></a><span class="tooltiptext code">template<typename T>
|
||
void ToIntSimStr16(benchmark::State& state, T t, int c) {
|
||
for (auto _: state) {
|
||
int res = t. template to_int<int, true, 16, false, false>().value;
|
||
#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">7.82</td><td class="benchmarkresult">7.84</td><td class="benchmarkresult">6.42</td><td class="benchmarkresult">12.6</td><td class="benchmarkresult">12.7</td><td class="benchmarkresult">16.1</td></tr>
|
||
</tbody></table></div><script>bench_sets['Convert to unsigned \'abcDef\''] = {id:'bs17', tests:[
|
||
{name:'std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);',data:[24.5,24.4,23.9,33.6,35.5,67.2]},
|
||
{name:'std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);',data:[9.59,22.0,9.15,8.50,8.96,18.3]},
|
||
{name:'stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>',data:[8.04,8.28,16.2,13.7,14.5,17.2]},
|
||
{name:'ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>',data:[7.57,7.65,6.48,7.50,13.3,16.7]},
|
||
{name:'lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>',data:[7.82,7.84,6.42,12.6,12.7,16.1]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs18"><h4><a id="bs52606100125109966680" href="#bs52606100125109966680">#</a> Convert to int ' 1234567'</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L842">std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);</a><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);
|
||
}
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">А здесь уже парсинг произвольного числа.
|
||
And here we have parsing of an arbitrary number.</span></span></td><td class="benchmarkresult">29.2</td><td class="benchmarkresult">29.4</td><td class="benchmarkresult">29.1</td><td class="benchmarkresult">43.6</td><td class="benchmarkresult">45.6</td><td class="benchmarkresult">97.3</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L913">stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow</a><span class="tooltiptext code">template<typename T>
|
||
void ToIntSimStr0(benchmark::State& state, T t, int c) {
|
||
for (auto _: state) {
|
||
int res = t. template to_int<int>().value;
|
||
#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">11.0</td><td class="benchmarkresult">11.4</td><td class="benchmarkresult">23.8</td><td class="benchmarkresult">17.3</td><td class="benchmarkresult">22.4</td><td class="benchmarkresult">13.7</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L928">ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow</a><span class="tooltiptext code">void ToIntNoOverflow(benchmark::State& state, ssa t, int c) {
|
||
for (auto _: state) {
|
||
int res = t.to_int<int, false>().value;
|
||
#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">13.3</td><td class="benchmarkresult">13.2</td><td class="benchmarkresult">11.0</td><td class="benchmarkresult">12.9</td><td class="benchmarkresult">19.1</td><td class="benchmarkresult">15.0</td></tr>
|
||
</tbody></table></div><script>bench_sets['Convert to int \' 1234567\''] = {id:'bs18', tests:[
|
||
{name:'std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);',data:[29.2,29.4,29.1,43.6,45.6,97.3]},
|
||
{name:'stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow',data:[11.0,11.4,23.8,17.3,22.4,13.7]},
|
||
{name:'ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow',data:[13.3,13.2,11.0,12.9,19.1,15.0]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs19"><h4><a id="bs182348477702821075660" href="#bs182348477702821075660">#</a> Convert to double '1234.567e10'</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L958">std::string s = "1234.567e10"; double res = std::strtod(s.c_str(), nullptr);</a><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">66.6</td><td class="benchmarkresult">65.8</td><td class="benchmarkresult">66.3</td><td class="benchmarkresult">100</td><td class="benchmarkresult">103</td><td class="benchmarkresult">298</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L975">std::string_view s = "1234.567e10"; std::from_chars(s.data(), s.data() + s.size(), res);</a><span class="tooltiptext code">template<typename K = char>
|
||
void ToDoubleFromChars(benchmark::State& state, const std::string_view& s, double c) {
|
||
for (auto _: state) {
|
||
double res = 0;
|
||
if constexpr (requires { std::from_chars(std::declval<K*>(), std::declval<K*>(), std::declval<double&>()); }) {
|
||
if (std::from_chars((const K*)s.data(), (const K*)s.data() + s.size(), res).ec != std::errc{}) {
|
||
state.SkipWithError("not equal");
|
||
}
|
||
} else {
|
||
state.SkipWithError("not implemented");
|
||
}
|
||
#ifdef CHECK_RESULT
|
||
if (res != c) {
|
||
state.SkipWithError("not equal");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(res);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">24.5</td><td class="benchmarkresult">Not impl</td><td class="benchmarkresult">24.4</td><td class="benchmarkresult">58.7</td><td class="benchmarkresult">82.7</td><td class="benchmarkresult">108</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L996">ssa s = "1234.567e10"; double res = *s.to_double()</a><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.8</td><td class="benchmarkresult">34.8</td><td class="benchmarkresult">24.5</td><td class="benchmarkresult">36.7</td><td class="benchmarkresult">37.7</td><td class="benchmarkresult">42.2</td></tr>
|
||
</tbody></table></div><script>bench_sets['Convert to double \'1234.567e10\''] = {id:'bs19', tests:[
|
||
{name:'std::string s = "1234.567e10"; double res = std::strtod(s.c_str(), nullptr);',data:[66.6,65.8,66.3,100,103,298]},
|
||
{name:'std::string_view s = "1234.567e10"; std::from_chars(s.data(), s.data() + s.size(), res);',data:[24.5,NaN,24.4,58.7,82.7,108]},
|
||
{name:'ssa s = "1234.567e10"; double res = *s.to_double()',data:[26.8,34.8,24.5,36.7,37.7,42.2]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs20"><h4><a id="bs96505608161678391610" href="#bs96505608161678391610">#</a> Append const literal of 16 bytes 64 times, 1024 total length</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1020">std::stringstream str; ... str << "abbaabbaabbaabba";</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1424</td><td class="benchmarkresult">2080</td><td class="benchmarkresult">1411</td><td class="benchmarkresult">5118</td><td class="benchmarkresult">5722</td><td class="benchmarkresult">6499</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1039">std::string str; ... str += "abbaabbaabbaabba";</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">445</td><td class="benchmarkresult">416</td><td class="benchmarkresult">380</td><td class="benchmarkresult">1073</td><td class="benchmarkresult">1306</td><td class="benchmarkresult">815</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1055">lstringa<8> str; ... str += "abbaabbaabbaabba";</a><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></td><td class="benchmarkresult">388</td><td class="benchmarkresult">362</td><td class="benchmarkresult">364</td><td class="benchmarkresult">767</td><td class="benchmarkresult">914</td><td class="benchmarkresult">794</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1055">lstringa<128> str; ... str += "abbaabbaabbaabba";</a><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">Чем больше внутренний буфер, тем меньше раз требуется
|
||
аллокация, тем быстрее результат.
|
||
The larger the internal buffer, the fewer allocations are
|
||
required, and the faster the result.</span></span></td><td class="benchmarkresult">276</td><td class="benchmarkresult">245</td><td class="benchmarkresult">271</td><td class="benchmarkresult">390</td><td class="benchmarkresult">542</td><td class="benchmarkresult">620</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1055">lstringa<512> str; ... str += "abbaabbaabbaabba";</a><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></td><td class="benchmarkresult">219</td><td class="benchmarkresult">217</td><td class="benchmarkresult">229</td><td class="benchmarkresult">239</td><td class="benchmarkresult">364</td><td class="benchmarkresult">401</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1055">lstringa<1024> str; ... str += "abbaabbaabbaabba";</a><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></td><td class="benchmarkresult">137</td><td class="benchmarkresult">136</td><td class="benchmarkresult">144</td><td class="benchmarkresult">158</td><td class="benchmarkresult">230</td><td class="benchmarkresult">335</td></tr>
|
||
</tbody></table></div><script>bench_sets['Append const literal of 16 bytes 64 times, 1024 total length'] = {id:'bs20', tests:[
|
||
{name:'std::stringstream str; ... str << "abbaabbaabbaabba";',data:[1424,2080,1411,5118,5722,6499]},
|
||
{name:'std::string str; ... str += "abbaabbaabbaabba";',data:[445,416,380,1073,1306,815]},
|
||
{name:'lstringa<8> str; ... str += "abbaabbaabbaabba";',data:[388,362,364,767,914,794]},
|
||
{name:'lstringa<128> str; ... str += "abbaabbaabbaabba";',data:[276,245,271,390,542,620]},
|
||
{name:'lstringa<512> str; ... str += "abbaabbaabbaabba";',data:[219,217,229,239,364,401]},
|
||
{name:'lstringa<1024> str; ... str += "abbaabbaabbaabba";',data:[137,136,144,158,230,335]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs21"><h4><a id="bs36931044816721597850" href="#bs36931044816721597850">#</a> Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1080">std::stringstream str; ... str << str_var << "abbaabbaabbaabba";</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1426</td><td class="benchmarkresult">2037</td><td class="benchmarkresult">1391</td><td class="benchmarkresult">4657</td><td class="benchmarkresult">5665</td><td class="benchmarkresult">7163</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1100">std::string str; ... str += str_var + "abbaabbaabbaabba";</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1288</td><td class="benchmarkresult">1253</td><td class="benchmarkresult">1161</td><td class="benchmarkresult">3774</td><td class="benchmarkresult">3902</td><td class="benchmarkresult">2186</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1118">lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">426</td><td class="benchmarkresult">401</td><td class="benchmarkresult">443</td><td class="benchmarkresult">716</td><td class="benchmarkresult">822</td><td class="benchmarkresult">890</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1118">lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">340</td><td class="benchmarkresult">335</td><td class="benchmarkresult">368</td><td class="benchmarkresult">442</td><td class="benchmarkresult">535</td><td class="benchmarkresult">864</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1118">lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">313</td><td class="benchmarkresult">291</td><td class="benchmarkresult">348</td><td class="benchmarkresult">303</td><td class="benchmarkresult">377</td><td class="benchmarkresult">722</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1118">lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">217</td><td class="benchmarkresult">214</td><td class="benchmarkresult">214</td><td class="benchmarkresult">188</td><td class="benchmarkresult">286</td><td class="benchmarkresult">639</td></tr>
|
||
</tbody></table></div><script>bench_sets['Append string of 16 bytes and const literal of 16 bytes 32 times, 1024 total length'] = {id:'bs21', tests:[
|
||
{name:'std::stringstream str; ... str << str_var << "abbaabbaabbaabba";',data:[1426,2037,1391,4657,5665,7163]},
|
||
{name:'std::string str; ... str += str_var + "abbaabbaabbaabba";',data:[1288,1253,1161,3774,3902,2186]},
|
||
{name:'lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";',data:[426,401,443,716,822,890]},
|
||
{name:'lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";',data:[340,335,368,442,535,864]},
|
||
{name:'lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";',data:[313,291,348,303,377,722]},
|
||
{name:'lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";',data:[217,214,214,188,286,639]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs22"><h4><a id="bs8293767858383349360" href="#bs8293767858383349360">#</a> Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1146">std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">75809</td><td class="benchmarkresult">159733</td><td class="benchmarkresult">75407</td><td class="benchmarkresult">221584</td><td class="benchmarkresult">295560</td><td class="benchmarkresult">348509</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1166">std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">73098</td><td class="benchmarkresult">104710</td><td class="benchmarkresult">67303</td><td class="benchmarkresult">183793</td><td class="benchmarkresult">199734</td><td class="benchmarkresult">120123</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1184">lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">19767</td><td class="benchmarkresult">49815</td><td class="benchmarkresult">20392</td><td class="benchmarkresult">19687</td><td class="benchmarkresult">25221</td><td class="benchmarkresult">44146</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1184">lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">17379</td><td class="benchmarkresult">27270</td><td class="benchmarkresult">17950</td><td class="benchmarkresult">16880</td><td class="benchmarkresult">23191</td><td class="benchmarkresult">44572</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1184">lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">16895</td><td class="benchmarkresult">16860</td><td class="benchmarkresult">17908</td><td class="benchmarkresult">17061</td><td class="benchmarkresult">21887</td><td class="benchmarkresult">44298</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1184">lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">17082</td><td class="benchmarkresult">16899</td><td class="benchmarkresult">17735</td><td class="benchmarkresult">16444</td><td class="benchmarkresult">22577</td><td class="benchmarkresult">44327</td></tr>
|
||
</tbody></table></div><script>bench_sets['Append string of 16 bytes and const literal of 16 bytes 2048 times, 65536 total length'] = {id:'bs22', tests:[
|
||
{name:'std::stringstream str; ... str << str_var << "abbaabbaabbaabba"; 2048 times',data:[75809,159733,75407,221584,295560,348509]},
|
||
{name:'std::string str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[73098,104710,67303,183793,199734,120123]},
|
||
{name:'lstringa<8> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[19767,49815,20392,19687,25221,44146]},
|
||
{name:'lstringa<128> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[17379,27270,17950,16880,23191,44572]},
|
||
{name:'lstringa<512> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[16895,16860,17908,17061,21887,44298]},
|
||
{name:'lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba"; 2048 times',data:[17082,16899,17735,16444,22577,44327]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs23"><h4><a id="bs66949588770596833730" href="#bs66949588770596833730">#</a> Append 2 string of 16 bytes 32 times, 1024 total length</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1211">std::stringstream str; ... str << str_var1 << str_var2;</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1469</td><td class="benchmarkresult">2073</td><td class="benchmarkresult">1397</td><td class="benchmarkresult">4403</td><td class="benchmarkresult">5538</td><td class="benchmarkresult">7317</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1233">std::string str; ... str += str_var1 + str_var2;</a><span class="tooltiptext code">void AppendStdStr2String(benchmark::State& state) {
|
||
std::string s1 = TEXT_16;
|
||
std::string s2 = TEXT_16;
|
||
|
||
for (auto _: state) {
|
||
std::string result;
|
||
for (size_t c = 0; c < 32; c++) {
|
||
result += s1 + s2;
|
||
}
|
||
#ifdef CHECK_RESULT
|
||
if (result.size() != 1024) {
|
||
state.SkipWithError("not equal");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(s1);
|
||
benchmark::DoNotOptimize(s2);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1415</td><td class="benchmarkresult">1492</td><td class="benchmarkresult">1344</td><td class="benchmarkresult">3893</td><td class="benchmarkresult">4019</td><td class="benchmarkresult">2607</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1254">lstringa<16> str; ... str += str_var1 + str_var2;</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">527</td><td class="benchmarkresult">476</td><td class="benchmarkresult">547</td><td class="benchmarkresult">794</td><td class="benchmarkresult">900</td><td class="benchmarkresult">1132</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1254">lstringa<128> str; ... str += str_var1 + str_var2;</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">465</td><td class="benchmarkresult">448</td><td class="benchmarkresult">454</td><td class="benchmarkresult">527</td><td class="benchmarkresult">641</td><td class="benchmarkresult">1062</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1254">lstringa<512> str; ... str += str_var1 + str_var2;</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">408</td><td class="benchmarkresult">379</td><td class="benchmarkresult">422</td><td class="benchmarkresult">381</td><td class="benchmarkresult">482</td><td class="benchmarkresult">914</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1254">lstringa<1024> str; ... str += str_var1 + str_var2;</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">309</td><td class="benchmarkresult">298</td><td class="benchmarkresult">310</td><td class="benchmarkresult">297</td><td class="benchmarkresult">365</td><td class="benchmarkresult">829</td></tr>
|
||
</tbody></table></div><script>bench_sets['Append 2 string of 16 bytes 32 times, 1024 total length'] = {id:'bs23', tests:[
|
||
{name:'std::stringstream str; ... str << str_var1 << str_var2;',data:[1469,2073,1397,4403,5538,7317]},
|
||
{name:'std::string str; ... str += str_var1 + str_var2;',data:[1415,1492,1344,3893,4019,2607]},
|
||
{name:'lstringa<16> str; ... str += str_var1 + str_var2;',data:[527,476,547,794,900,1132]},
|
||
{name:'lstringa<128> str; ... str += str_var1 + str_var2;',data:[465,448,454,527,641,1062]},
|
||
{name:'lstringa<512> str; ... str += str_var1 + str_var2;',data:[408,379,422,381,482,914]},
|
||
{name:'lstringa<1024> str; ... str += str_var1 + str_var2;',data:[309,298,310,297,365,829]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs24"><h4><a id="bs130432147582115154460" href="#bs130432147582115154460">#</a> Append text, number, text</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1283">std::stringstream str; str << "test = " << k << " times";</a><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);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">3067</td><td class="benchmarkresult">3419</td><td class="benchmarkresult">3033</td><td class="benchmarkresult">10833</td><td class="benchmarkresult">11725</td><td class="benchmarkresult">11412</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1301">std::string str = "test = " + std::to_string(k) + " times";</a><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);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">457</td><td class="benchmarkresult">474</td><td class="benchmarkresult">427</td><td class="benchmarkresult">1053</td><td class="benchmarkresult">1226</td><td class="benchmarkresult">1772</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1317">char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;</a><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);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1393</td><td class="benchmarkresult">1229</td><td class="benchmarkresult">1487</td><td class="benchmarkresult">2810</td><td class="benchmarkresult">2815</td><td class="benchmarkresult">5285</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1335">std::string str = std::format("test = {} times", k);</a><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);
|
||
}
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1140</td><td class="benchmarkresult">959</td><td class="benchmarkresult">1206</td><td class="benchmarkresult">1904</td><td class="benchmarkresult">2391</td><td class="benchmarkresult">2834</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1351">lstringa<8> str; str.format("test = {} times", k);</a><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);
|
||
}
|
||
}
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">В simstr format с первого раза не помещается в такую строку без аллокации.
|
||
In simstr format, the first time it doesn't fit into such a
|
||
string without allocation.</span></span></td><td class="benchmarkresult">1356</td><td class="benchmarkresult">2002</td><td class="benchmarkresult">1559</td><td class="benchmarkresult">2003</td><td class="benchmarkresult">2677</td><td class="benchmarkresult">4681</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1351">lstringa<32> str; str.format("test = {} times", k);</a><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);
|
||
}
|
||
}
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">А в такую помещается. Используйте сразу буфера подходящего размера.
|
||
And it fits in this one. Use buffers of the appropriate size right away.</span></span></td><td class="benchmarkresult">1002</td><td class="benchmarkresult">1745</td><td class="benchmarkresult">1054</td><td class="benchmarkresult">962</td><td class="benchmarkresult">1480</td><td class="benchmarkresult">4054</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1369">lstringa<8> str = "test = " + k + " times";</a><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, возникает аллокация.
|
||
The result does not fit into SSO, an allocation occurs.</span></span></td><td class="benchmarkresult">262</td><td class="benchmarkresult">263</td><td class="benchmarkresult">290</td><td class="benchmarkresult">807</td><td class="benchmarkresult">890</td><td class="benchmarkresult">555</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1369">lstringa<32> str = "test = " + k + " times";</a><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.
|
||
Ещё раз - используйте сразу буфера подходящего размера.
|
||
And here and below, the result fits within SSO.
|
||
Once again, use appropriately sized buffers from the start.</span></span></td><td class="benchmarkresult">126</td><td class="benchmarkresult">119</td><td class="benchmarkresult">136</td><td class="benchmarkresult">134</td><td class="benchmarkresult">180</td><td class="benchmarkresult">339</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1369">stringa str = "test = " + k + " times";</a><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 символов, что явно не хватает для размещения
|
||
результата, отсюда и такое время.
|
||
Under WASM, the SSO size is 15 characters, which is clearly not
|
||
enough to accommodate the result, hence the long time.</span></span></td><td class="benchmarkresult">124</td><td class="benchmarkresult">118</td><td class="benchmarkresult">137</td><td class="benchmarkresult">126</td><td class="benchmarkresult">172</td><td class="benchmarkresult">511</td></tr>
|
||
</tbody></table></div><script>bench_sets['Append text, number, text'] = {id:'bs24', tests:[
|
||
{name:'std::stringstream str; str << "test = " << k << " times";',data:[3067,3419,3033,10833,11725,11412]},
|
||
{name:'std::string str = "test = " + std::to_string(k) + " times";',data:[457,474,427,1053,1226,1772]},
|
||
{name:'char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;',data:[1393,1229,1487,2810,2815,5285]},
|
||
{name:'std::string str = std::format("test = {} times", k);',data:[1140,959,1206,1904,2391,2834]},
|
||
{name:'lstringa<8> str; str.format("test = {} times", k);',data:[1356,2002,1559,2003,2677,4681]},
|
||
{name:'lstringa<32> str; str.format("test = {} times", k);',data:[1002,1745,1054,962,1480,4054]},
|
||
{name:'lstringa<8> str = "test = " + k + " times";',data:[262,263,290,807,890,555]},
|
||
{name:'lstringa<32> str = "test = " + k + " times";',data:[126,119,136,134,180,339]},
|
||
{name:'stringa str = "test = " + k + " times";',data:[124,118,137,126,172,511]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs25"><h4><a id="bs7106975351756760120" href="#bs7106975351756760120">#</a> Split text and convert to int</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1399">std::string::find + substr + std::strtol</a><span class="tooltiptext code">void SplitConvertIntStdString(benchmark::State& 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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">270</td><td class="benchmarkresult">277</td><td class="benchmarkresult">275</td><td class="benchmarkresult">558</td><td class="benchmarkresult">573</td><td class="benchmarkresult">660</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1423">ssa::splitter + ssa::as_int</a><span class="tooltiptext code">void SplitConvertIntSimStr(benchmark::State& 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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">156</td><td class="benchmarkresult">159</td><td class="benchmarkresult">192</td><td class="benchmarkresult">176</td><td class="benchmarkresult">304</td><td class="benchmarkresult">245</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1440">ssa::splitf + functor</a><span class="tooltiptext code">void SplitConvertIntSplitf(benchmark::State& 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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">207</td><td class="benchmarkresult">213</td><td class="benchmarkresult">196</td><td class="benchmarkresult">192</td><td class="benchmarkresult">218</td><td class="benchmarkresult">271</td></tr>
|
||
</tbody></table></div><script>bench_sets['Split text and convert to int'] = {id:'bs25', tests:[
|
||
{name:'std::string::find + substr + std::strtol',data:[270,277,275,558,573,660]},
|
||
{name:'ssa::splitter + ssa::as_int',data:[156,159,192,176,304,245]},
|
||
{name:'ssa::splitf + functor',data:[207,213,196,192,218,271]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs26"><h4><a id="bs151373809886162287550" href="#bs151373809886162287550">#</a> Replace symbols in text ~400 symbols</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1461">Naive (and wrong) replace symbols with std::string find + replace</a><span class="tooltiptext code">void ReplaceSymbolsStdStringNaiveWrong(benchmark::State& 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'. Но если замены не конфликтуют,
|
||
то работает быстро.
|
||
This is a naive implementation that will fail to handle substitutions
|
||
such as 'a'->'b' and 'b'->'a'. But if the substitutions don't conflict,
|
||
it works quickly.</span></span></td><td class="benchmarkresult">844</td><td class="benchmarkresult">916</td><td class="benchmarkresult">822</td><td class="benchmarkresult">1124</td><td class="benchmarkresult">1206</td><td class="benchmarkresult">2872</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1515">replace symbols with std::string find_first_of + replace</a><span class="tooltiptext code">void ReplaceSymbolsStdStringNaiveRight(benchmark::State& 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);
|
||
}
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">Дальше уже правильные реализации, не зависящие от конфликтующих замен.
|
||
Further, there are correct implementations that do not depend on
|
||
conflicting replacements.</span></span></td><td class="benchmarkresult">2647</td><td class="benchmarkresult">2428</td><td class="benchmarkresult">2428</td><td class="benchmarkresult">1940</td><td class="benchmarkresult">2200</td><td class="benchmarkresult">5223</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1569">replace symbols with std::string_view find_first_of + copy</a><span class="tooltiptext code">void ReplaceSymbolsStdString(benchmark::State& state) {
|
||
std::string_view source =
|
||
"abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >"
|
||
" ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf"
|
||
"abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >"
|
||
" ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf"
|
||
"abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >"
|
||
" ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf"
|
||
"abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >"
|
||
" ksjd-fksjd \"dkjfs-jkhdf dfj ' kdkd \"dkfdkfkdjf"
|
||
;
|
||
|
||
const std::string_view repl_from = "-<>'\"&";
|
||
const std::string_view repl_to[] = {"", "&lt;", "&gt;", "&#39;", "&quot;", "&amp;"};
|
||
|
||
for (auto _: state) {
|
||
std::string result;
|
||
|
||
for (size_t start = 0; start < source.size();) {
|
||
size_t idx = source.find_first_of(repl_from, start);
|
||
if (idx == std::string::npos) {
|
||
result += source.substr(start);
|
||
break;
|
||
}
|
||
if (idx > start) {
|
||
result += source.substr(start, idx - start);
|
||
}
|
||
size_t what = repl_from.find(source[idx]);
|
||
result += repl_to[what];
|
||
|
||
start = idx + 1;
|
||
}
|
||
#ifdef CHECK_RESULT
|
||
if (result
|
||
!=
|
||
"abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;"
|
||
" ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf"
|
||
"abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;"
|
||
" ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf"
|
||
"abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;"
|
||
" ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf"
|
||
"abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;"
|
||
" ksjdfksjd &quot;dkjfsjkhdf dfj &#39; kdkd &quot;dkfdkfkdjf"
|
||
) {
|
||
state.SkipWithError("not equal");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(source);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1123</td><td class="benchmarkresult">1026</td><td class="benchmarkresult">1065</td><td class="benchmarkresult">2359</td><td class="benchmarkresult">2544</td><td class="benchmarkresult">2704</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1622">replace runtime symbols with string expressions and without remembering all search results</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1273</td><td class="benchmarkresult">1408</td><td class="benchmarkresult">1372</td><td class="benchmarkresult">1654</td><td class="benchmarkresult">1663</td><td class="benchmarkresult">2675</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1622">replace runtime symbols with simstr and memorization of all search results</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1067</td><td class="benchmarkresult">1083</td><td class="benchmarkresult">1016</td><td class="benchmarkresult">1483</td><td class="benchmarkresult">1442</td><td class="benchmarkresult">2107</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1669">replace const symbols with string expressions and without remembering all search results</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1029</td><td class="benchmarkresult">1128</td><td class="benchmarkresult">1045</td><td class="benchmarkresult">1122</td><td class="benchmarkresult">1293</td><td class="benchmarkresult">2227</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1669">replace const symbols with string expressions and memorization of all search results</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">887</td><td class="benchmarkresult">820</td><td class="benchmarkresult">837</td><td class="benchmarkresult">1170</td><td class="benchmarkresult">1213</td><td class="benchmarkresult">1872</td></tr>
|
||
</tbody></table></div><script>bench_sets['Replace symbols in text ~400 symbols'] = {id:'bs26', tests:[
|
||
{name:'Naive (and wrong) replace symbols with std::string find + replace',data:[844,916,822,1124,1206,2872]},
|
||
{name:'replace symbols with std::string find_first_of + replace',data:[2647,2428,2428,1940,2200,5223]},
|
||
{name:'replace symbols with std::string_view find_first_of + copy',data:[1123,1026,1065,2359,2544,2704]},
|
||
{name:'replace runtime symbols with string expressions and without remembering all search results',data:[1273,1408,1372,1654,1663,2675]},
|
||
{name:'replace runtime symbols with simstr and memorization of all search results',data:[1067,1083,1016,1483,1442,2107]},
|
||
{name:'replace const symbols with string expressions and without remembering all search results',data:[1029,1128,1045,1122,1293,2227]},
|
||
{name:'replace const symbols with string expressions and memorization of all search results',data:[887,820,837,1170,1213,1872]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs27"><h4><a id="bs96756339547767401190" href="#bs96756339547767401190">#</a> Replace symbols in text ~40 symbols</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1723">Short Naive (and wrong) replace symbols with std::string find + replace</a><span class="tooltiptext code">void ShortReplaceSymbolsStdStringNaiveWrong(benchmark::State& 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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">166</td><td class="benchmarkresult">177</td><td class="benchmarkresult">161</td><td class="benchmarkresult">308</td><td class="benchmarkresult">328</td><td class="benchmarkresult">472</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1763">Short replace symbols with std::string find_first_of + replace</a><span class="tooltiptext code">void ShortReplaceSymbolsStdStringNaiveRight(benchmark::State& 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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">334</td><td class="benchmarkresult">324</td><td class="benchmarkresult">329</td><td class="benchmarkresult">364</td><td class="benchmarkresult">420</td><td class="benchmarkresult">718</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1803">Short replace symbols with std::string_view find_first_of + copy</a><span class="tooltiptext code">void ShortReplaceSymbolsStdString(benchmark::State& state) {
|
||
std::string_view source =
|
||
"abcdefg124 < jhsfjsh sjdfsh jfhjd && jdjdj >"
|
||
;
|
||
|
||
const std::string_view repl_from = "-<>'\"&";
|
||
const std::string_view repl_to[] = {"", "&lt;", "&gt;", "&#39;", "&quot;", "&amp;"};
|
||
|
||
for (auto _: state) {
|
||
std::string result;
|
||
|
||
for (size_t start = 0; start < source.size();) {
|
||
size_t idx = source.find_first_of(repl_from, start);
|
||
if (idx == std::string::npos) {
|
||
result += source.substr(start);
|
||
break;
|
||
}
|
||
if (idx > start) {
|
||
result += source.substr(start, idx - start);
|
||
}
|
||
size_t what = repl_from.find_first_of(source[idx]);
|
||
result += repl_to[what];
|
||
|
||
start = idx + 1;
|
||
}
|
||
#ifdef CHECK_RESULT
|
||
if (result
|
||
!=
|
||
"abcdefg124 &lt; jhsfjsh sjdfsh jfhjd &amp;&amp; jdjdj &gt;"
|
||
) {
|
||
state.SkipWithError("not equal");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(source);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">154</td><td class="benchmarkresult">141</td><td class="benchmarkresult">154</td><td class="benchmarkresult">305</td><td class="benchmarkresult">333</td><td class="benchmarkresult">433</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1842">Short replace runtime symbols with string expressions and without remembering all search results</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">169</td><td class="benchmarkresult">198</td><td class="benchmarkresult">180</td><td class="benchmarkresult">269</td><td class="benchmarkresult">310</td><td class="benchmarkresult">378</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1842">Short replace runtime symbols with simstr and memorization of all search results</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">201</td><td class="benchmarkresult">186</td><td class="benchmarkresult">184</td><td class="benchmarkresult">366</td><td class="benchmarkresult">401</td><td class="benchmarkresult">391</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1875">Short replace const symbols with string expressions and without remembering all search results</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">130</td><td class="benchmarkresult">126</td><td class="benchmarkresult">139</td><td class="benchmarkresult">202</td><td class="benchmarkresult">254</td><td class="benchmarkresult">271</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1875">Short replace const symbols with string expressions and memorization of all search results</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">145</td><td class="benchmarkresult">136</td><td class="benchmarkresult">132</td><td class="benchmarkresult">293</td><td class="benchmarkresult">334</td><td class="benchmarkresult">294</td></tr>
|
||
</tbody></table></div><script>bench_sets['Replace symbols in text ~40 symbols'] = {id:'bs27', tests:[
|
||
{name:'Short Naive (and wrong) replace symbols with std::string find + replace',data:[166,177,161,308,328,472]},
|
||
{name:'Short replace symbols with std::string find_first_of + replace',data:[334,324,329,364,420,718]},
|
||
{name:'Short replace symbols with std::string_view find_first_of + copy',data:[154,141,154,305,333,433]},
|
||
{name:'Short replace runtime symbols with string expressions and without remembering all search results',data:[169,198,180,269,310,378]},
|
||
{name:'Short replace runtime symbols with simstr and memorization of all search results',data:[201,186,184,366,401,391]},
|
||
{name:'Short replace const symbols with string expressions and without remembering all search results',data:[130,126,139,202,254,271]},
|
||
{name:'Short replace const symbols with string expressions and memorization of all search results',data:[145,136,132,293,334,294]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs28"><h4><a id="bs77745698784557935900" href="#bs77745698784557935900">#</a> Replace All Str To Longer Size</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1914">replace bb to ---- in std::string|64</a><span class="tooltiptext code">template<size_t Long>
|
||
void ReplaceAllLongerStdString(benchmark::State& state) {
|
||
std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
std::string_view sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a";
|
||
|
||
std::string_view pattern = "bb";
|
||
std::string_view repl = "----";
|
||
|
||
std::string big_source, big_sample;
|
||
for (int i = 0; i < Long; i++) {
|
||
big_source += source;
|
||
big_sample += sample;
|
||
}
|
||
|
||
for (auto _: state) {
|
||
std::string result{big_source};
|
||
size_t start_pos = 0;
|
||
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
|
||
result.replace(start_pos, pattern.length(), repl);
|
||
start_pos += repl.length();
|
||
}
|
||
#ifdef CHECK_RESULT
|
||
if (result != big_sample) {
|
||
state.SkipWithError("error in replace");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(source);
|
||
benchmark::DoNotOptimize(pattern);
|
||
benchmark::DoNotOptimize(repl);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">151</td><td class="benchmarkresult">180</td><td class="benchmarkresult">154</td><td class="benchmarkresult">223</td><td class="benchmarkresult">242</td><td class="benchmarkresult">363</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1914">replace bb to ---- in std::string|256</a><span class="tooltiptext code">template<size_t Long>
|
||
void ReplaceAllLongerStdString(benchmark::State& state) {
|
||
std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
std::string_view sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a";
|
||
|
||
std::string_view pattern = "bb";
|
||
std::string_view repl = "----";
|
||
|
||
std::string big_source, big_sample;
|
||
for (int i = 0; i < Long; i++) {
|
||
big_source += source;
|
||
big_sample += sample;
|
||
}
|
||
|
||
for (auto _: state) {
|
||
std::string result{big_source};
|
||
size_t start_pos = 0;
|
||
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
|
||
result.replace(start_pos, pattern.length(), repl);
|
||
start_pos += repl.length();
|
||
}
|
||
#ifdef CHECK_RESULT
|
||
if (result != big_sample) {
|
||
state.SkipWithError("error in replace");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(source);
|
||
benchmark::DoNotOptimize(pattern);
|
||
benchmark::DoNotOptimize(repl);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">603</td><td class="benchmarkresult">842</td><td class="benchmarkresult">504</td><td class="benchmarkresult">727</td><td class="benchmarkresult">791</td><td class="benchmarkresult">1189</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1914">replace bb to ---- in std::string|512</a><span class="tooltiptext code">template<size_t Long>
|
||
void ReplaceAllLongerStdString(benchmark::State& state) {
|
||
std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
std::string_view sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a";
|
||
|
||
std::string_view pattern = "bb";
|
||
std::string_view repl = "----";
|
||
|
||
std::string big_source, big_sample;
|
||
for (int i = 0; i < Long; i++) {
|
||
big_source += source;
|
||
big_sample += sample;
|
||
}
|
||
|
||
for (auto _: state) {
|
||
std::string result{big_source};
|
||
size_t start_pos = 0;
|
||
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
|
||
result.replace(start_pos, pattern.length(), repl);
|
||
start_pos += repl.length();
|
||
}
|
||
#ifdef CHECK_RESULT
|
||
if (result != big_sample) {
|
||
state.SkipWithError("error in replace");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(source);
|
||
benchmark::DoNotOptimize(pattern);
|
||
benchmark::DoNotOptimize(repl);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1060</td><td class="benchmarkresult">1259</td><td class="benchmarkresult">1000</td><td class="benchmarkresult">1418</td><td class="benchmarkresult">1464</td><td class="benchmarkresult">2210</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1914">replace bb to ---- in std::string|1024</a><span class="tooltiptext code">template<size_t Long>
|
||
void ReplaceAllLongerStdString(benchmark::State& state) {
|
||
std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
std::string_view sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a";
|
||
|
||
std::string_view pattern = "bb";
|
||
std::string_view repl = "----";
|
||
|
||
std::string big_source, big_sample;
|
||
for (int i = 0; i < Long; i++) {
|
||
big_source += source;
|
||
big_sample += sample;
|
||
}
|
||
|
||
for (auto _: state) {
|
||
std::string result{big_source};
|
||
size_t start_pos = 0;
|
||
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
|
||
result.replace(start_pos, pattern.length(), repl);
|
||
start_pos += repl.length();
|
||
}
|
||
#ifdef CHECK_RESULT
|
||
if (result != big_sample) {
|
||
state.SkipWithError("error in replace");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(source);
|
||
benchmark::DoNotOptimize(pattern);
|
||
benchmark::DoNotOptimize(repl);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">2332</td><td class="benchmarkresult">2422</td><td class="benchmarkresult">2347</td><td class="benchmarkresult">3058</td><td class="benchmarkresult">3204</td><td class="benchmarkresult">4756</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1914">replace bb to ---- in std::string|2048</a><span class="tooltiptext code">template<size_t Long>
|
||
void ReplaceAllLongerStdString(benchmark::State& state) {
|
||
std::string_view source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
std::string_view sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a";
|
||
|
||
std::string_view pattern = "bb";
|
||
std::string_view repl = "----";
|
||
|
||
std::string big_source, big_sample;
|
||
for (int i = 0; i < Long; i++) {
|
||
big_source += source;
|
||
big_sample += sample;
|
||
}
|
||
|
||
for (auto _: state) {
|
||
std::string result{big_source};
|
||
size_t start_pos = 0;
|
||
while((start_pos = result.find(pattern, start_pos)) != std::string::npos) {
|
||
result.replace(start_pos, pattern.length(), repl);
|
||
start_pos += repl.length();
|
||
}
|
||
#ifdef CHECK_RESULT
|
||
if (result != big_sample) {
|
||
state.SkipWithError("error in replace");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(source);
|
||
benchmark::DoNotOptimize(pattern);
|
||
benchmark::DoNotOptimize(repl);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">5851</td><td class="benchmarkresult">6347</td><td class="benchmarkresult">5969</td><td class="benchmarkresult">8038</td><td class="benchmarkresult">8080</td><td class="benchmarkresult">11109</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1948">replace bb to ---- in lstringa<8>|64</a><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";
|
||
|
||
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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">127</td><td class="benchmarkresult">129</td><td class="benchmarkresult">138</td><td class="benchmarkresult">216</td><td class="benchmarkresult">225</td><td class="benchmarkresult">292</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1948">replace bb to ---- in lstringa<8>|256</a><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";
|
||
|
||
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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">442</td><td class="benchmarkresult">444</td><td class="benchmarkresult">444</td><td class="benchmarkresult">606</td><td class="benchmarkresult">655</td><td class="benchmarkresult">913</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1948">replace bb to ---- in lstringa<8>|512</a><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";
|
||
|
||
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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">831</td><td class="benchmarkresult">828</td><td class="benchmarkresult">899</td><td class="benchmarkresult">1002</td><td class="benchmarkresult">1124</td><td class="benchmarkresult">1685</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1948">replace bb to ---- in lstringa<8>|1024</a><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";
|
||
|
||
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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1698</td><td class="benchmarkresult">1614</td><td class="benchmarkresult">1751</td><td class="benchmarkresult">1848</td><td class="benchmarkresult">2038</td><td class="benchmarkresult">3100</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1948">replace bb to ---- in lstringa<8>|2048</a><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";
|
||
|
||
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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">3256</td><td class="benchmarkresult">3127</td><td class="benchmarkresult">3301</td><td class="benchmarkresult">3556</td><td class="benchmarkresult">3964</td><td class="benchmarkresult">6119</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1971">replace bb to ---- by init stringa|64</a><span class="tooltiptext code">template<size_t Count>
|
||
void ReplaceAllLongerSimStringExpr(benchmark::State& state) {
|
||
ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a";
|
||
|
||
lstringa<2048> big_source{Count, source}, big_sample{Count, sample};
|
||
|
||
for (auto _: state) {
|
||
stringa result = e_repl(big_source, "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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">91.5</td><td class="benchmarkresult">90.9</td><td class="benchmarkresult">92.8</td><td class="benchmarkresult">165</td><td class="benchmarkresult">196</td><td class="benchmarkresult">187</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1971">replace bb to ---- by init stringa|256</a><span class="tooltiptext code">template<size_t Count>
|
||
void ReplaceAllLongerSimStringExpr(benchmark::State& state) {
|
||
ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a";
|
||
|
||
lstringa<2048> big_source{Count, source}, big_sample{Count, sample};
|
||
|
||
for (auto _: state) {
|
||
stringa result = e_repl(big_source, "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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">306</td><td class="benchmarkresult">308</td><td class="benchmarkresult">287</td><td class="benchmarkresult">366</td><td class="benchmarkresult">456</td><td class="benchmarkresult">580</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1971">replace bb to ---- by init stringa|512</a><span class="tooltiptext code">template<size_t Count>
|
||
void ReplaceAllLongerSimStringExpr(benchmark::State& state) {
|
||
ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a";
|
||
|
||
lstringa<2048> big_source{Count, source}, big_sample{Count, sample};
|
||
|
||
for (auto _: state) {
|
||
stringa result = e_repl(big_source, "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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">718</td><td class="benchmarkresult">709</td><td class="benchmarkresult">705</td><td class="benchmarkresult">793</td><td class="benchmarkresult">1064</td><td class="benchmarkresult">1341</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1971">replace bb to ---- by init stringa|1024</a><span class="tooltiptext code">template<size_t Count>
|
||
void ReplaceAllLongerSimStringExpr(benchmark::State& state) {
|
||
ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a";
|
||
|
||
lstringa<2048> big_source{Count, source}, big_sample{Count, sample};
|
||
|
||
for (auto _: state) {
|
||
stringa result = e_repl(big_source, "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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1629</td><td class="benchmarkresult">1392</td><td class="benchmarkresult">1550</td><td class="benchmarkresult">1626</td><td class="benchmarkresult">2161</td><td class="benchmarkresult">2813</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1971">replace bb to ---- by init stringa|2048</a><span class="tooltiptext code">template<size_t Count>
|
||
void ReplaceAllLongerSimStringExpr(benchmark::State& state) {
|
||
ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
ssa sample = "aaaaaaaaaaaaaaaaaaa----baaaaaaaa--------aaaaabaaaaaaaaaaaaaaaaaaaaa----a";
|
||
|
||
lstringa<2048> big_source{Count, source}, big_sample{Count, sample};
|
||
|
||
for (auto _: state) {
|
||
stringa result = e_repl(big_source, "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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">3400</td><td class="benchmarkresult">2810</td><td class="benchmarkresult">3106</td><td class="benchmarkresult">3047</td><td class="benchmarkresult">4481</td><td class="benchmarkresult">5550</td></tr>
|
||
</tbody></table></div><script>bench_sets['Replace All Str To Longer Size'] = {id:'bs28', tests:[
|
||
{name:'replace bb to ---- in std::string|64',data:[151,180,154,223,242,363]},
|
||
{name:'replace bb to ---- in std::string|256',data:[603,842,504,727,791,1189]},
|
||
{name:'replace bb to ---- in std::string|512',data:[1060,1259,1000,1418,1464,2210]},
|
||
{name:'replace bb to ---- in std::string|1024',data:[2332,2422,2347,3058,3204,4756]},
|
||
{name:'replace bb to ---- in std::string|2048',data:[5851,6347,5969,8038,8080,11109]},
|
||
{name:'replace bb to ---- in lstringa<8>|64',data:[127,129,138,216,225,292]},
|
||
{name:'replace bb to ---- in lstringa<8>|256',data:[442,444,444,606,655,913]},
|
||
{name:'replace bb to ---- in lstringa<8>|512',data:[831,828,899,1002,1124,1685]},
|
||
{name:'replace bb to ---- in lstringa<8>|1024',data:[1698,1614,1751,1848,2038,3100]},
|
||
{name:'replace bb to ---- in lstringa<8>|2048',data:[3256,3127,3301,3556,3964,6119]},
|
||
{name:'replace bb to ---- by init stringa|64',data:[91.5,90.9,92.8,165,196,187]},
|
||
{name:'replace bb to ---- by init stringa|256',data:[306,308,287,366,456,580]},
|
||
{name:'replace bb to ---- by init stringa|512',data:[718,709,705,793,1064,1341]},
|
||
{name:'replace bb to ---- by init stringa|1024',data:[1629,1392,1550,1626,2161,2813]},
|
||
{name:'replace bb to ---- by init stringa|2048',data:[3400,2810,3106,3047,4481,5550]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs29"><h4><a id="bs74494088982050398630" href="#bs74494088982050398630">#</a> Replace All Str To Same Size</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1993">replace bb to -- in std::string|64</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">114</td><td class="benchmarkresult">130</td><td class="benchmarkresult">131</td><td class="benchmarkresult">187</td><td class="benchmarkresult">198</td><td class="benchmarkresult">243</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1993">replace bb to -- in std::string|256</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">390</td><td class="benchmarkresult">427</td><td class="benchmarkresult">381</td><td class="benchmarkresult">469</td><td class="benchmarkresult">520</td><td class="benchmarkresult">814</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1993">replace bb to -- in std::string|512</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">743</td><td class="benchmarkresult">851</td><td class="benchmarkresult">743</td><td class="benchmarkresult">837</td><td class="benchmarkresult">928</td><td class="benchmarkresult">1542</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1993">replace bb to -- in std::string|1024</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1477</td><td class="benchmarkresult">1603</td><td class="benchmarkresult">1483</td><td class="benchmarkresult">1612</td><td class="benchmarkresult">1750</td><td class="benchmarkresult">2825</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L1993">replace bb to -- in std::string|2048</a><span class="tooltiptext code">template<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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">2929</td><td class="benchmarkresult">3230</td><td class="benchmarkresult">2798</td><td class="benchmarkresult">3131</td><td class="benchmarkresult">3402</td><td class="benchmarkresult">5545</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2026">replace bb to -- in lstringa<8>|64</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">89.2</td><td class="benchmarkresult">90.8</td><td class="benchmarkresult">91.5</td><td class="benchmarkresult">175</td><td class="benchmarkresult">186</td><td class="benchmarkresult">192</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2026">replace bb to -- in lstringa<8>|256</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">295</td><td class="benchmarkresult">294</td><td class="benchmarkresult">302</td><td class="benchmarkresult">427</td><td class="benchmarkresult">442</td><td class="benchmarkresult">636</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2026">replace bb to -- in lstringa<8>|512</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">553</td><td class="benchmarkresult">551</td><td class="benchmarkresult">539</td><td class="benchmarkresult">723</td><td class="benchmarkresult">771</td><td class="benchmarkresult">1150</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2026">replace bb to -- in lstringa<8>|1024</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1122</td><td class="benchmarkresult">1066</td><td class="benchmarkresult">1121</td><td class="benchmarkresult">1373</td><td class="benchmarkresult">1457</td><td class="benchmarkresult">2296</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2026">replace bb to -- in lstringa<8>|2048</a><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);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">2088</td><td class="benchmarkresult">2242</td><td class="benchmarkresult">2174</td><td class="benchmarkresult">2685</td><td class="benchmarkresult">2800</td><td class="benchmarkresult">4237</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2048">replace bb to -- by init stringa|64</a><span class="tooltiptext code">template<size_t Count>
|
||
void ReplaceAllEqualSimStringExpr(benchmark::State& state) {
|
||
ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a";
|
||
ssa pattern = "bb";
|
||
ssa repl = "--";
|
||
|
||
lstringa<2048> big_source{Count, source}, big_sample{Count, sample};
|
||
|
||
for (auto _: state) {
|
||
stringa result = e_repl(big_source.to_str(), "bb", "--");
|
||
|
||
#ifdef CHECK_RESULT
|
||
if (result.to_str() != big_sample) {
|
||
std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n";
|
||
state.SkipWithError("error in replace");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(source);
|
||
benchmark::DoNotOptimize(pattern);
|
||
benchmark::DoNotOptimize(repl);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">73.9</td><td class="benchmarkresult">83.0</td><td class="benchmarkresult">112</td><td class="benchmarkresult">153</td><td class="benchmarkresult">165</td><td class="benchmarkresult">136</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2048">replace bb to -- by init stringa|256</a><span class="tooltiptext code">template<size_t Count>
|
||
void ReplaceAllEqualSimStringExpr(benchmark::State& state) {
|
||
ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a";
|
||
ssa pattern = "bb";
|
||
ssa repl = "--";
|
||
|
||
lstringa<2048> big_source{Count, source}, big_sample{Count, sample};
|
||
|
||
for (auto _: state) {
|
||
stringa result = e_repl(big_source.to_str(), "bb", "--");
|
||
|
||
#ifdef CHECK_RESULT
|
||
if (result.to_str() != big_sample) {
|
||
std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n";
|
||
state.SkipWithError("error in replace");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(source);
|
||
benchmark::DoNotOptimize(pattern);
|
||
benchmark::DoNotOptimize(repl);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">240</td><td class="benchmarkresult">237</td><td class="benchmarkresult">262</td><td class="benchmarkresult">322</td><td class="benchmarkresult">367</td><td class="benchmarkresult">464</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2048">replace bb to -- by init stringa|512</a><span class="tooltiptext code">template<size_t Count>
|
||
void ReplaceAllEqualSimStringExpr(benchmark::State& state) {
|
||
ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a";
|
||
ssa pattern = "bb";
|
||
ssa repl = "--";
|
||
|
||
lstringa<2048> big_source{Count, source}, big_sample{Count, sample};
|
||
|
||
for (auto _: state) {
|
||
stringa result = e_repl(big_source.to_str(), "bb", "--");
|
||
|
||
#ifdef CHECK_RESULT
|
||
if (result.to_str() != big_sample) {
|
||
std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n";
|
||
state.SkipWithError("error in replace");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(source);
|
||
benchmark::DoNotOptimize(pattern);
|
||
benchmark::DoNotOptimize(repl);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">434</td><td class="benchmarkresult">435</td><td class="benchmarkresult">479</td><td class="benchmarkresult">520</td><td class="benchmarkresult">632</td><td class="benchmarkresult">838</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2048">replace bb to -- by init stringa|1024</a><span class="tooltiptext code">template<size_t Count>
|
||
void ReplaceAllEqualSimStringExpr(benchmark::State& state) {
|
||
ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a";
|
||
ssa pattern = "bb";
|
||
ssa repl = "--";
|
||
|
||
lstringa<2048> big_source{Count, source}, big_sample{Count, sample};
|
||
|
||
for (auto _: state) {
|
||
stringa result = e_repl(big_source.to_str(), "bb", "--");
|
||
|
||
#ifdef CHECK_RESULT
|
||
if (result.to_str() != big_sample) {
|
||
std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n";
|
||
state.SkipWithError("error in replace");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(source);
|
||
benchmark::DoNotOptimize(pattern);
|
||
benchmark::DoNotOptimize(repl);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">898</td><td class="benchmarkresult">851</td><td class="benchmarkresult">954</td><td class="benchmarkresult">954</td><td class="benchmarkresult">1108</td><td class="benchmarkresult">1620</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2048">replace bb to -- by init stringa|2048</a><span class="tooltiptext code">template<size_t Count>
|
||
void ReplaceAllEqualSimStringExpr(benchmark::State& state) {
|
||
ssa source = "aaaaaaaaaaaaaaaaaaabbbaaaaaaaabbbbaaaaabaaaaaaaaaaaaaaaaaaaaabba";
|
||
ssa sample = "aaaaaaaaaaaaaaaaaaa--baaaaaaaa----aaaaabaaaaaaaaaaaaaaaaaaaaa--a";
|
||
ssa pattern = "bb";
|
||
ssa repl = "--";
|
||
|
||
lstringa<2048> big_source{Count, source}, big_sample{Count, sample};
|
||
|
||
for (auto _: state) {
|
||
stringa result = e_repl(big_source.to_str(), "bb", "--");
|
||
|
||
#ifdef CHECK_RESULT
|
||
if (result.to_str() != big_sample) {
|
||
std::cout << result.length() << ": " << result << "\n\n" << big_sample.length() << ": " << big_sample << "\n\n";
|
||
state.SkipWithError("error in replace");
|
||
break;
|
||
}
|
||
#endif
|
||
benchmark::DoNotOptimize(result);
|
||
benchmark::DoNotOptimize(source);
|
||
benchmark::DoNotOptimize(pattern);
|
||
benchmark::DoNotOptimize(repl);
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">1709</td><td class="benchmarkresult">1658</td><td class="benchmarkresult">1809</td><td class="benchmarkresult">1806</td><td class="benchmarkresult">2118</td><td class="benchmarkresult">2774</td></tr>
|
||
</tbody></table></div><script>bench_sets['Replace All Str To Same Size'] = {id:'bs29', tests:[
|
||
{name:'replace bb to -- in std::string|64',data:[114,130,131,187,198,243]},
|
||
{name:'replace bb to -- in std::string|256',data:[390,427,381,469,520,814]},
|
||
{name:'replace bb to -- in std::string|512',data:[743,851,743,837,928,1542]},
|
||
{name:'replace bb to -- in std::string|1024',data:[1477,1603,1483,1612,1750,2825]},
|
||
{name:'replace bb to -- in std::string|2048',data:[2929,3230,2798,3131,3402,5545]},
|
||
{name:'replace bb to -- in lstringa<8>|64',data:[89.2,90.8,91.5,175,186,192]},
|
||
{name:'replace bb to -- in lstringa<8>|256',data:[295,294,302,427,442,636]},
|
||
{name:'replace bb to -- in lstringa<8>|512',data:[553,551,539,723,771,1150]},
|
||
{name:'replace bb to -- in lstringa<8>|1024',data:[1122,1066,1121,1373,1457,2296]},
|
||
{name:'replace bb to -- in lstringa<8>|2048',data:[2088,2242,2174,2685,2800,4237]},
|
||
{name:'replace bb to -- by init stringa|64',data:[73.9,83.0,112,153,165,136]},
|
||
{name:'replace bb to -- by init stringa|256',data:[240,237,262,322,367,464]},
|
||
{name:'replace bb to -- by init stringa|512',data:[434,435,479,520,632,838]},
|
||
{name:'replace bb to -- by init stringa|1024',data:[898,851,954,954,1108,1620]},
|
||
{name:'replace bb to -- by init stringa|2048',data:[1709,1658,1809,1806,2118,2774]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs30"><h4><a id="bs8410196985047277720" href="#bs8410196985047277720">#</a> Hash Map insert and find</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2145">hashStrMapA<size_t> emplace & find stringa;</a><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
|
||
символов, а потом ищем их в ней
|
||
We insert 10,000 strings of length from 30 to 50 characters into
|
||
hashStrMapA, and then search for them in it.</span></span></td><td class="benchmarkresult">3754473</td><td class="benchmarkresult">3780026</td><td class="benchmarkresult">3843202</td><td class="benchmarkresult">4069702</td><td class="benchmarkresult">4479657</td><td class="benchmarkresult">3271665</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2169">std::unordered_map<std::string, size_t> emplace & find std::string;</a><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);
|
||
}
|
||
}
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">То же самое c std::string и std::unordered_map
|
||
Same thing with std::string and std::unordered_map</span></span></td><td class="benchmarkresult">3584569</td><td class="benchmarkresult">3706958</td><td class="benchmarkresult">3689411</td><td class="benchmarkresult">5913523</td><td class="benchmarkresult">6065832</td><td class="benchmarkresult">3592775</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2193">hashStrMapA<size_t> emplace & find ssa;</a><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);
|
||
}
|
||
}
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">Теперь вставляем stringa, а ищем ssa
|
||
Now we insert stringa and search for ssa</span></span></td><td class="benchmarkresult">3718652</td><td class="benchmarkresult">3815600</td><td class="benchmarkresult">3848145</td><td class="benchmarkresult">3619495</td><td class="benchmarkresult">4127357</td><td class="benchmarkresult">3244867</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2218">std::unordered_map<std::string, size_t> emplace & find std::string_view;</a><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);
|
||
}
|
||
}
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">Вставляем std::string, а ищем std::string_view
|
||
We insert std::string and look for std::string_view</span></span></td><td class="benchmarkresult">4196609</td><td class="benchmarkresult">4134155</td><td class="benchmarkresult">4076242</td><td class="benchmarkresult">6497268</td><td class="benchmarkresult">6592167</td><td class="benchmarkresult">4041903</td></tr>
|
||
</tbody></table></div><script>bench_sets['Hash Map insert and find'] = {id:'bs30', tests:[
|
||
{name:'hashStrMapA<size_t> emplace & find stringa;',data:[3754473,3780026,3843202,4069702,4479657,3271665]},
|
||
{name:'std::unordered_map<std::string, size_t> emplace & find std::string;',data:[3584569,3706958,3689411,5913523,6065832,3592775]},
|
||
{name:'hashStrMapA<size_t> emplace & find ssa;',data:[3718652,3815600,3848145,3619495,4127357,3244867]},
|
||
{name:'std::unordered_map<std::string, size_t> emplace & find std::string_view;',data:[4196609,4134155,4076242,6497268,6592167,4041903]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs31"><h4><a id="bs131384792586914680410" href="#bs131384792586914680410">#</a> Build Full Func Name</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2428">Build func full name std::string;</a><span class="tooltiptext code">std::string build_full_name_std() const {
|
||
std::string str{has_ret_type_resolver ? "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">Обыденная задача, подобные часто могут встретится в работе:
|
||
По неким данным сгенерировать текст. В этом случае по данным
|
||
о неких функциях сформировать их полное имя с типами параметров и
|
||
возвращаемого значения. Алгоритм на std::string.
|
||
A common task, similar to this one, can often be encountered in work:
|
||
Generate text from given data. In this case, using data
|
||
on certain functions, generate their full names with parameter types and
|
||
return values. The algorithm uses std::string.</span></span></td><td class="benchmarkresult">673</td><td class="benchmarkresult">1021</td><td class="benchmarkresult">738</td><td class="benchmarkresult">1507</td><td class="benchmarkresult">1622</td><td class="benchmarkresult">3162</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2460">Build func full name std::string 1;</a><span class="tooltiptext code">std::string build_full_name_std1() const {
|
||
std::string str{has_ret_type_resolver ? "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">Почти тот же алгоритм, но несколько последовательных
|
||
+= к строке заменены на одно += + + +.
|
||
Almost the same algorithm, but several consecutive
|
||
+= to a string are replaced with a single += + + +.</span></span></td><td class="benchmarkresult">768</td><td class="benchmarkresult">1021</td><td class="benchmarkresult">820</td><td class="benchmarkresult">1515</td><td class="benchmarkresult">1697</td><td class="benchmarkresult">3363</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2490">Build func full name std::stream;</a><span class="tooltiptext code">std::string build_full_name_stream() const {
|
||
std::ostringstream str;
|
||
if (has_ret_type_resolver) {
|
||
str << "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();
|
||
}</span></span></td><td><span class="tooltip info"> >> <span class="tooltiptext">Строим имя функции через std::ostringstream и <<
|
||
We construct the function name through std::ostringstream and <<</span></span></td><td class="benchmarkresult">3165</td><td class="benchmarkresult">2984</td><td class="benchmarkresult">2610</td><td class="benchmarkresult">8296</td><td class="benchmarkresult">9698</td><td class="benchmarkresult">11876</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2401">Build func full name stringa;</a><span class="tooltiptext code">stringa build_full_name() const {
|
||
lstringa<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 строках и строковых выражениях.
|
||
Инфа о параметрах добавляется в текущую строку
|
||
Implementation using simstr strings and string expressions.
|
||
Parameter information is appended to the current line.</span></span></td><td class="benchmarkresult">472</td><td class="benchmarkresult">471</td><td class="benchmarkresult">480</td><td class="benchmarkresult">749</td><td class="benchmarkresult">867</td><td class="benchmarkresult">1461</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2416">Build func full name stringa 1;</a><span class="tooltiptext code">stringa build_full_name1() const {
|
||
lstringa<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 строках и строковых выражениях.
|
||
Инфа о параметрах добавляется во временную строку, а потом
|
||
разом добавляется в текущую строку. Позволяет операции в цикле
|
||
записать в одну строку, но чуть проигрывает по времени выполнения.
|
||
Implementation using simstr strings and string expressions.
|
||
Parameter information is added to a temporary string, and then
|
||
all at once to the current string. This allows loop operations
|
||
to be written in a single string, but is slightly slower in execution time.</span></span></td><td class="benchmarkresult">616</td><td class="benchmarkresult">648</td><td class="benchmarkresult">564</td><td class="benchmarkresult">878</td><td class="benchmarkresult">996</td><td class="benchmarkresult">1910</td></tr>
|
||
</tbody></table></div><script>bench_sets['Build Full Func Name'] = {id:'bs31', tests:[
|
||
{name:'Build func full name std::string;',data:[673,1021,738,1507,1622,3162]},
|
||
{name:'Build func full name std::string 1;',data:[768,1021,820,1515,1697,3363]},
|
||
{name:'Build func full name std::stream;',data:[3165,2984,2610,8296,9698,11876]},
|
||
{name:'Build func full name stringa;',data:[472,471,480,749,867,1461]},
|
||
{name:'Build func full name stringa 1;',data:[616,648,564,878,996,1910]}
|
||
]}</script>
|
||
|
||
<div class="benchset" id="bs32"><h4><a id="bs36691618230457010710" href="#bs36691618230457010710">#</a> Make Upper</h4>
|
||
<table><thead><tr><th>Benchmark name</th><th width="5%">Comment</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), Clang-22 libc++</th><th width="6%">Xeon E5-2682 v4, Ubuntu 22 (WSL), GCC-15</th><th width="6%">Xeon E5-2682 v4, Windows 10, Clang-22</th><th width="6%">Xeon E5-2682 v4, Windows 10, MSVC-19</th><th width="6%">Xeon E5-2682 v4, WASM Chrome 143, Clang-22</th></tr></thead><tbody>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2630">To upper case std::wstring</a><span class="tooltiptext code">void UpperCaseStd(benchmark::State& state) {
|
||
static const auto& loc = std::locale("en_US.utf8");
|
||
|
||
for (auto _: state) {
|
||
std::wstring test = L"TestПриветTest";
|
||
benchmark::DoNotOptimize(test);
|
||
|
||
std::transform(test.begin(), test.end(), test.begin(), [](wchar_t s) {
|
||
return std::toupper(s, loc);
|
||
});
|
||
|
||
benchmark::DoNotOptimize(test);
|
||
#ifdef CHECK_RESULT
|
||
if (test != L"TESTПРИВЕТTEST") {
|
||
state.SkipWithError("Bad upper case");
|
||
}
|
||
#endif
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">162</td><td class="benchmarkresult">175</td><td class="benchmarkresult">175</td><td class="benchmarkresult">1457</td><td class="benchmarkresult">1438</td><td class="benchmarkresult">204</td></tr>
|
||
<tr><td class="benchmarkname"><span class="tooltip"><a target="blank" href="https://github.com/orefkov/simstr/blob/rel1.8.1/bench/bench_str.cpp#L2650">To upper case lstringw<15></a><span class="tooltiptext code">void UpperCaseSim(benchmark::State& state) {
|
||
for (auto _: state) {
|
||
lstringw<15> test = L"TestПриветTest";
|
||
benchmark::DoNotOptimize(test);
|
||
|
||
test.upper();
|
||
|
||
benchmark::DoNotOptimize(test);
|
||
#ifdef CHECK_RESULT
|
||
if (test != L"TESTПРИВЕТTEST") {
|
||
state.SkipWithError("Bad upper case");
|
||
}
|
||
#endif
|
||
}
|
||
}</span></span></td><td></td><td class="benchmarkresult">43.7</td><td class="benchmarkresult">38.5</td><td class="benchmarkresult">40.4</td><td class="benchmarkresult">41.0</td><td class="benchmarkresult">44.4</td><td class="benchmarkresult">63.1</td></tr>
|
||
</tbody></table></div><script>bench_sets['Make Upper'] = {id:'bs32', tests:[
|
||
{name:'To upper case std::wstring',data:[162,175,175,1457,1438,204]},
|
||
{name:'To upper case lstringw<15>',data:[43.7,38.5,40.4,41.0,44.4,63.1]}
|
||
]}</script></body></html> |