2026-01-21 11:59:17 +00:00
|
|
|
|
- Concat stringa and number by StrExpr to simstr::stringa
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
|
|
- Find concat three simstr
|
|
|
|
|
|
Если результат конкатенации меньше 207 символов,
|
|
|
|
|
|
он собирается в буфере на стеке, без аллокации и деалокации.
|
|
|
|
|
|
If the concatenation result is less than 207 characters,
|
|
|
|
|
|
it is collected in a stack-based buffer, without allocation or deallocation.
|
|
|
|
|
|
|
|
|
|
|
|
- Concat with replace exp
|
|
|
|
|
|
В simstr строковое выражение для замены подстрок
|
|
|
|
|
|
есть "из коробки".
|
|
|
|
|
|
simstr has a string expression for replacing substrings out of the box.
|
|
|
|
|
|
|
2025-04-05 14:21:11 +00:00
|
|
|
|
- std::string e;
|
|
|
|
|
|
Пустые строки, ничего необычного.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Empty lines, nothing unusual.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string_view e;
|
|
|
|
|
|
- ssa e;
|
|
|
|
|
|
- stringa e;
|
|
|
|
|
|
- lstringa<20> e;
|
|
|
|
|
|
- lstringa<40> e;
|
|
|
|
|
|
|
|
|
|
|
|
- std::string e = "Test text";
|
|
|
|
|
|
Короткий литерал помещается во внутренний буфер std::string,
|
|
|
|
|
|
время тратится только на копирование 10 байтов.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
The short literal is placed in the internal std::string buffer;
|
|
|
|
|
|
time is spent only copying 10 bytes.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string_view e = "Test text";
|
|
|
|
|
|
И string_view, и ssa - по сути одно и то же:
|
|
|
|
|
|
указатель на текст и его длина.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Both string_view and ssa are essentially the same thing:
|
|
|
|
|
|
a pointer to text and its length.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- ssa e = "Test text";
|
|
|
|
|
|
- stringa e = "Test text";
|
|
|
|
|
|
stringa при инициализации константным литералом так же
|
|
|
|
|
|
сохраняет только указатель на текст и его длину.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
When initialized with a constant literal, stringa also stores
|
|
|
|
|
|
only a pointer to the text and its length.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<20> e = "Test text";
|
|
|
|
|
|
Внутреннего буфера хватает для размещения символов,
|
|
|
|
|
|
время уходит только на копирование байтов.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
The internal buffer is sufficient to accommodate characters;
|
|
|
|
|
|
time is spent only on copying bytes.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<40> e = "Test text";
|
|
|
|
|
|
- std::string e = "123456789012345678901234567890";
|
|
|
|
|
|
Вот тут уже литерал не помещается во внутренний буфер,
|
|
|
|
|
|
возникает аллокация и копирование 30-и байтов.
|
|
|
|
|
|
Но как же отстает аллокация под Windows от Linux'а, 20 vs 70 ns...
|
2026-01-21 11:59:17 +00:00
|
|
|
|
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...
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string_view e = "123456789012345678901234567890";
|
|
|
|
|
|
string_view и ssa по прежнему ничего не делают, кроме
|
|
|
|
|
|
запоминания указателя на текст и его размера.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
string_view and ssa still do nothing except
|
|
|
|
|
|
remember the pointer to the text and its size.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- ssa e = "123456789012345678901234567890";
|
|
|
|
|
|
- stringa e = "123456789012345678901234567890";
|
|
|
|
|
|
stringa на константных литералах не отстает!
|
2026-01-21 11:59:17 +00:00
|
|
|
|
stringa doesn't lag behind on constant literals!
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<20> e = "123456789012345678901234567890";
|
|
|
|
|
|
lstringa<20> может вместить в себя до 23 символов,
|
|
|
|
|
|
Очевидно, что для 30-и символов уже нужна аллокация.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Obviously, 30 characters already require allocation.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<40> e = "123456789012345678901234567890";
|
|
|
|
|
|
А в lstringa<40> влезает до 47 символов, так что просто
|
|
|
|
|
|
копируется 30 байтов.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
And lstringa<40> can hold up to 47 characters, so 30
|
|
|
|
|
|
bytes are simply copied.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string e = "Test text"; auto c{e};
|
|
|
|
|
|
Строка в пределах SSO, так что просто копирует байты.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
The string is within the SSO, so it just copies the bytes.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string_view e = "Test text"; auto c{e};
|
|
|
|
|
|
- ssa e = "Test text"; auto c{e};
|
|
|
|
|
|
ssa и string_view не владеют строкой, копируется
|
|
|
|
|
|
только информация о строке.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
ssa and string_view don't own the string; only the
|
|
|
|
|
|
string information is copied.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- stringa e = "Test text"; auto c{e};
|
|
|
|
|
|
Копирование stringa происходит быстро,
|
|
|
|
|
|
особенно если она инициализирована литералом.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Copying a stringa is fast,
|
|
|
|
|
|
especially if it is initialized with a literal.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<20> e = "Test text"; auto c{e};
|
|
|
|
|
|
В обоих случаях хватает внутреннего буфера.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
In both cases, the internal buffer is sufficient.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<40> e = "Test text"; auto c{e};
|
|
|
|
|
|
Только копируются байты.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Only bytes are copied.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string e = "123456789012345678901234567890"; auto c{e};
|
|
|
|
|
|
Копирования длинной строки вызывает аллокацию,
|
|
|
|
|
|
SSO уже не хватает. И снова как же отстаёт аллокация под Windows...
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Copying a long string causes allocations,
|
|
|
|
|
|
SSO is no longer sufficient. And again, how allocation lags under Windows...
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string_view e = "123456789012345678901234567890"; auto c{e};
|
|
|
|
|
|
- ssa e = "123456789012345678901234567890"; auto c{e};
|
|
|
|
|
|
- stringa e = "123456789012345678901234567890"; auto c{e};
|
|
|
|
|
|
А вот у stringa копирование литерала не зависит от его длины,
|
|
|
|
|
|
сравни с предыдущим бенчмарком.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
But with stringa, literal copying doesn't depend on its length,
|
|
|
|
|
|
compare with the previous benchmark.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<20> e = "123456789012345678901234567890"; auto c{e};
|
|
|
|
|
|
Не влезает, аллокация.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Doesn't fit, allocation.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<40> e = "123456789012345678901234567890"; auto c{e};
|
|
|
|
|
|
Уложили во внутренний буфер.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Placed in the internal buffer.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string::find;
|
|
|
|
|
|
Здесь "победила дружба", у всех типов по колонке примерно одинаково.
|
|
|
|
|
|
Однако, Windows и Linux явно в разных весовых категориях.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Here, "friendship wins," with all types scoring roughly equally.
|
|
|
|
|
|
However, Windows and Linux are clearly in different weight classes.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string_view::find;
|
|
|
|
|
|
- ssa::find;
|
|
|
|
|
|
- stringa::find;
|
|
|
|
|
|
- lstringa<20>::find;
|
|
|
|
|
|
- lstringa<40>::find;
|
|
|
|
|
|
- std::string copy{str_with_len_N};/15
|
|
|
|
|
|
- std::string copy{str_with_len_N};/16
|
|
|
|
|
|
Явно виден скачок, где заканчивается SSO и начинается аллокация.
|
|
|
|
|
|
Обратите внимание, что WASM - 32-битный, и там размер
|
2026-02-12 16:47:32 +00:00
|
|
|
|
SSO у std::string меньше, 10 символов + 0.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
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.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string copy{str_with_len_N};/23
|
|
|
|
|
|
Дальше просто добавляется время на копирование байтов.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Then the time for copying bytes is simply added.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string copy{str_with_len_N};/24
|
|
|
|
|
|
- std::string copy{str_with_len_N};/32
|
|
|
|
|
|
- std::string copy{str_with_len_N};/64
|
|
|
|
|
|
- std::string copy{str_with_len_N};/128
|
|
|
|
|
|
- std::string copy{str_with_len_N};/256
|
|
|
|
|
|
- std::string copy{str_with_len_N};/512
|
|
|
|
|
|
- std::string copy{str_with_len_N};/1024
|
|
|
|
|
|
- std::string copy{str_with_len_N};/2048
|
|
|
|
|
|
- std::string copy{str_with_len_N};/4096
|
|
|
|
|
|
Чем длиннее строка, тем дольше создаётся копия.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
The longer the string, the longer it takes to create a copy.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- stringa copy{str_with_len_N};/15
|
|
|
|
|
|
Здесь stringa инициализируется не литералом,
|
|
|
|
|
|
а значит, должна сама хранить символы.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Here, stringa is not initialized with a literal,
|
|
|
|
|
|
meaning it must store characters itself.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- stringa copy{str_with_len_N};/16
|
|
|
|
|
|
Под WASM SSO у stringa составляет 15 символов. Кроме того,
|
2026-01-21 11:59:17 +00:00
|
|
|
|
собиралось без поддержки потоков, поэтому атомарный
|
2025-04-05 14:21:11 +00:00
|
|
|
|
инкремент заменён на обычный, судя по времени.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
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.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- stringa copy{str_with_len_N};/23
|
|
|
|
|
|
SSO в stringa до 23 символов, и даже 23
|
|
|
|
|
|
копируются быстрее, чем 15 в std::string.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
SSO in stringa is up to 23 characters, and even 23
|
|
|
|
|
|
copies faster than 15 in std::string.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- stringa copy{str_with_len_N};/24
|
|
|
|
|
|
Всё, не влезаем в SSO, а значит, используем shared буфер.
|
|
|
|
|
|
Добавляется время на атомарный инкремент счётчика.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
That's it, we're not using SSO, so we're using a shared buffer.
|
|
|
|
|
|
Time is added for the atomic counter increment.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- stringa copy{str_with_len_N};/32
|
|
|
|
|
|
- stringa copy{str_with_len_N};/64
|
|
|
|
|
|
- stringa copy{str_with_len_N};/128
|
|
|
|
|
|
- stringa copy{str_with_len_N};/256
|
|
|
|
|
|
- stringa copy{str_with_len_N};/512
|
|
|
|
|
|
- stringa copy{str_with_len_N};/1024
|
|
|
|
|
|
- stringa copy{str_with_len_N};/2048
|
|
|
|
|
|
- stringa copy{str_with_len_N};/4096
|
|
|
|
|
|
И как видно, кроме инкремента нет накладных расходов,
|
|
|
|
|
|
время копирования не зависит от длины строки.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
And as you can see, there are no overhead costs other than the
|
|
|
|
|
|
increment; copying time does not depend on the string length.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<16> copy{str_with_len_N};/15
|
|
|
|
|
|
lstringa<16> использует SSO до 23 символов.
|
|
|
|
|
|
А в WASM 32-битная архитектура, SSO до 19 символов.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
lstringa<16> uses SSO up to 23 characters.
|
|
|
|
|
|
WASM has a 32-bit architecture, so SSO is up to 19 characters.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<16> copy{str_with_len_N};/16
|
|
|
|
|
|
- lstringa<16> copy{str_with_len_N};/23
|
|
|
|
|
|
- lstringa<16> copy{str_with_len_N};/24
|
|
|
|
|
|
И после начинает вести себя при копировании, как std::string.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
And then it starts to behave like std::string when copied.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<16> copy{str_with_len_N};/32
|
|
|
|
|
|
- lstringa<16> copy{str_with_len_N};/64
|
|
|
|
|
|
- lstringa<16> copy{str_with_len_N};/128
|
|
|
|
|
|
- lstringa<16> copy{str_with_len_N};/256
|
|
|
|
|
|
- lstringa<16> copy{str_with_len_N};/512
|
|
|
|
|
|
- lstringa<16> copy{str_with_len_N};/1024
|
|
|
|
|
|
- lstringa<16> copy{str_with_len_N};/2048
|
|
|
|
|
|
- lstringa<16> copy{str_with_len_N};/4096
|
|
|
|
|
|
- lstringa<512> copy{str_with_len_N};/8
|
|
|
|
|
|
А вот lstringa<512> имеет гораздо больший внутренний
|
|
|
|
|
|
буфер и копирует символы без аллокации.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
But lstringa<512> has a much larger internal
|
|
|
|
|
|
buffer and copies characters without allocation.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<512> copy{str_with_len_N};/16
|
|
|
|
|
|
- lstringa<512> copy{str_with_len_N};/32
|
|
|
|
|
|
- lstringa<512> copy{str_with_len_N};/64
|
|
|
|
|
|
- lstringa<512> copy{str_with_len_N};/128
|
|
|
|
|
|
- lstringa<512> copy{str_with_len_N};/256
|
|
|
|
|
|
- lstringa<512> copy{str_with_len_N};/512
|
|
|
|
|
|
Даже 512 символов копируются быстрее, чем
|
|
|
|
|
|
одна аллокация или атомарный инкремент.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Even 512 characters are copied faster than a single
|
|
|
|
|
|
allocation or atomic increment.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<512> copy{str_with_len_N};/1024
|
2026-01-21 11:59:17 +00:00
|
|
|
|
А дальше уже как у всех.
|
|
|
|
|
|
And then it's like everyone else.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<512> copy{str_with_len_N};/2048
|
|
|
|
|
|
- lstringa<512> copy{str_with_len_N};/4096
|
|
|
|
|
|
|
|
|
|
|
|
- std::string s = "123456789"; int res = std::strtol(s.c_str(), 0, 10);
|
|
|
|
|
|
В simstr для конвертации в число достаточно куска строки,
|
|
|
|
|
|
нет нужды в null терминированности. Ближайший аналог такого
|
|
|
|
|
|
поведения "std::from_chars", но он к сожалению очень ограничен
|
|
|
|
|
|
по возможностям. Здесь я попытался произвести тесты, близкие по
|
|
|
|
|
|
логике к работе std::from_chars
|
2026-01-21 11:59:17 +00:00
|
|
|
|
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.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string_view s = "123456789"; std::from_chars(s.data(), s.data() + s.size(), res, 10);
|
|
|
|
|
|
from_chars требует точного указания основания счисления,
|
|
|
|
|
|
не допускает знаков плюс, пробелов, префиксов 0x и т.п.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
from_chars requires an exact radix specification and does not allow plus
|
|
|
|
|
|
signs, spaces, 0x prefixes, etc.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- stringa s = "123456789"; int res = s.to_int<int, true, 10, false>
|
|
|
|
|
|
Здесь для to_int заданы такие же ограничения - проверять переполнение,
|
|
|
|
|
|
десятичная система, без лидирующих пробелов и знака плюс
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Here, to_int has the same restrictions: check for overflow,
|
|
|
|
|
|
decimal system, no leading spaces, and no plus sign.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- ssa s = "123456789"; int res = s.to_int<int, true, 10, false>
|
|
|
|
|
|
- lstringa<20> s = "123456789"; int res = s.to_int<int, true, 10, false>
|
|
|
|
|
|
- std::string s = "abcDef"; int res = std::strtol(s.c_str(), 0, 16);
|
|
|
|
|
|
Всё то же, только для 16ричной системы
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Everything is the same, only for the hexadecimal system
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string_view s = "abcDef"; std::from_chars(s.data(), s.data() + s.size(), res, 16);
|
|
|
|
|
|
- stringa s = "abcDef"; int res = s.to_int<int, true, 16, false>
|
|
|
|
|
|
- ssa s = "abcDef"; int res = s.to_int<int, true, 16, false>
|
|
|
|
|
|
- lstringa<20> s = "abcDef"; int res = s.to_int<int, true, 16, false>
|
|
|
|
|
|
- std::string s = " 123456789"; int res = std::strtol(s.c_str(), 0, 0);
|
|
|
|
|
|
А здесь уже парсинг произвольного числа.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
And here we have parsing of an arbitrary number.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- stringa s = " 123456789"; int res = s.to_int<int>; // Check overflow
|
|
|
|
|
|
- ssa s = " 123456789"; int res = s.to_int<int, false>; // No check overflow
|
|
|
|
|
|
- std::stringstream str; ... str << "abbaabbaabbaabba";
|
|
|
|
|
|
- std::string str; ... str += "abbaabbaabbaabba";
|
|
|
|
|
|
- lstringa<8> str; ... str += "abbaabbaabbaabba";
|
|
|
|
|
|
- lstringa<128> str; ... str += "abbaabbaabbaabba";
|
|
|
|
|
|
Чем больше внутренний буфер, тем меньше раз требуется
|
|
|
|
|
|
аллокация, тем быстрее результат.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
The larger the internal buffer, the fewer allocations are
|
|
|
|
|
|
required, and the faster the result.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<512> str; ... str += "abbaabbaabbaabba";
|
|
|
|
|
|
- lstringa<1024> str; ... str += "abbaabbaabbaabba";
|
|
|
|
|
|
- std::stringstream str; ... str << str_var << "abbaabbaabbaabba";
|
|
|
|
|
|
- std::string str; ... str += str_var + "abbaabbaabbaabba";
|
|
|
|
|
|
- lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";
|
|
|
|
|
|
- lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";
|
|
|
|
|
|
- lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";
|
|
|
|
|
|
- lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";
|
|
|
|
|
|
- std::stringstream str; ... str << str_var << "abbaabbaabbaabba";
|
|
|
|
|
|
- std::string str; ... str += str_var + "abbaabbaabbaabba";
|
|
|
|
|
|
- lstringa<8> str; ... str += str_var + "abbaabbaabbaabba";
|
|
|
|
|
|
- lstringa<128> str; ... str += str_var + "abbaabbaabbaabba";
|
|
|
|
|
|
- lstringa<512> str; ... str += str_var + "abbaabbaabbaabba";
|
|
|
|
|
|
- lstringa<1024> str; ... str += str_var + "abbaabbaabbaabba";
|
|
|
|
|
|
- std::stringstream str; ... str << str_var1 << str_var2;
|
|
|
|
|
|
- std::string str; ... str += str_var1 + str_var2;
|
|
|
|
|
|
- lstringa<16> str; ... str += str_var1 + str_var2;
|
|
|
|
|
|
- lstringa<128> str; ... str += str_var1 + str_var2;
|
|
|
|
|
|
- lstringa<512> str; ... str += str_var1 + str_var2;
|
|
|
|
|
|
- lstringa<1024> str; ... str += str_var1 + str_var2;
|
|
|
|
|
|
- std::stringstream str; str << "test = " << k << " times";
|
|
|
|
|
|
- std::string str = "test = " + std::to_string(k) + " times";
|
|
|
|
|
|
- char buf[100]; sprintf(buf, "test = %u times", k); std::string str = buf;
|
|
|
|
|
|
- std::string str = std::format("test = {} times", k);
|
|
|
|
|
|
- lstringa<8> str; str.format("test = {} times", k);
|
|
|
|
|
|
В simstr format с первого раза не помещается в такую строку без аллокации.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
In simstr format, the first time it doesn't fit into such a
|
|
|
|
|
|
string without allocation.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<32> str; str.format("test = {} times", k);
|
|
|
|
|
|
А в такую помещается. Используйте сразу буфера подходящего размера.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
And it fits in this one. Use buffers of the appropriate size right away.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<8> str = "test = " + k + " times";
|
|
|
|
|
|
Результат не помещается в SSO, возникает аллокация.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
The result does not fit into SSO, an allocation occurs.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- lstringa<32> str = "test = " + k + " times";
|
|
|
|
|
|
А здесь и ниже - результат укладывается в SSO.
|
|
|
|
|
|
Ещё раз - используйте сразу буфера подходящего размера.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
And here and below, the result fits within SSO.
|
|
|
|
|
|
Once again, use appropriately sized buffers from the start.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- stringa str = "test = " + k + " times";
|
|
|
|
|
|
Под WASM размер SSO 15 символов, что явно не хватает для размещения
|
|
|
|
|
|
результата, отсюда и такое время.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Under WASM, the SSO size is 15 characters, which is clearly not
|
|
|
|
|
|
enough to accommodate the result, hence the long time.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::string::find + substr + std::strtol
|
|
|
|
|
|
- ssa::splitter + ssa::as_int
|
|
|
|
|
|
|
|
|
|
|
|
- Naive (and wrong) replace symbols with std::string find + replace
|
|
|
|
|
|
Это наивная реализация, которая неверно отработает на
|
|
|
|
|
|
таких заменах, как 'a'->'b' и 'b'->'a'. Но если замены не конфликтуют,
|
|
|
|
|
|
то работает быстро.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
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.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- replace symbols with std::string find_first_of + replace
|
|
|
|
|
|
Дальше уже правильные реализации, не зависящие от конфликтующих замен.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Further, there are correct implementations that do not depend on
|
|
|
|
|
|
conflicting replacements.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- replace symbols with std::string_view find_first_of + copy
|
|
|
|
|
|
- replace runtime symbols with string expressions and without remembering all search results
|
|
|
|
|
|
- replace runtime symbols with simstr and memorization of all search results
|
|
|
|
|
|
- replace const symbols with string expressions and without remembering all search results
|
|
|
|
|
|
- replace const symbols with string expressions and memorization of all search results
|
|
|
|
|
|
- Short Naive (and wrong) replace symbols with std::string find + replace
|
|
|
|
|
|
- Short replace symbols with std::string find_first_of + replace
|
|
|
|
|
|
- Short replace symbols with std::string_view find_first_of + copy
|
|
|
|
|
|
- Short replace runtime symbols with string expressions and without remembering all search results
|
|
|
|
|
|
- Short replace runtime symbols with simstr and memorization of all search results
|
|
|
|
|
|
- Short replace const symbols with string expressions and without remembering all search results
|
|
|
|
|
|
- Short replace const symbols with string expressions and memorization of all search results
|
|
|
|
|
|
|
|
|
|
|
|
- replace bb to ---- in 64 std::string
|
|
|
|
|
|
Тут проверяется тяжелый случай - замена подстроки на более
|
|
|
|
|
|
длинную. Обычная реализация несколько раз передвигает хвост.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
This checks for a difficult case: replacing a substring with a longer
|
|
|
|
|
|
one. The standard implementation moves the tail several times.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- replace bb to ---- in 64 lstringa<8>
|
|
|
|
|
|
- replace bb to ---- in 64 str by init stringa
|
|
|
|
|
|
- replace bb to ---- in 256 std::string
|
|
|
|
|
|
- replace bb to ---- in 256 lstringa<8>
|
|
|
|
|
|
- replace bb to ---- in 256 str by init stringa
|
|
|
|
|
|
- replace bb to ---- in 512 std::string
|
|
|
|
|
|
- replace bb to ---- in 512 lstringa<8>
|
|
|
|
|
|
- replace bb to ---- in 512 str by init stringa
|
|
|
|
|
|
- replace bb to ---- in 1024 std::string
|
|
|
|
|
|
- replace bb to ---- in 1024 lstringa<8>
|
|
|
|
|
|
- replace bb to ---- in 1024 str by init stringa
|
|
|
|
|
|
- replace bb to ---- in 2048 std::string
|
|
|
|
|
|
Чем длиннее строка, тем больше замедляется std::string
|
2026-01-21 11:59:17 +00:00
|
|
|
|
The longer the string, the slower std::string becomes.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- replace bb to ---- in 2048 lstringa<8>
|
|
|
|
|
|
- replace bb to ---- in 2048 str by init stringa
|
|
|
|
|
|
- replace bb to -- in 64 std::string
|
|
|
|
|
|
Идеальный случай замены - на подстроку такой же длины
|
2026-01-21 11:59:17 +00:00
|
|
|
|
The ideal case of replacement is with a substring of the same length.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- replace bb to -- in 64 lstringa<8>
|
|
|
|
|
|
- replace bb to -- in 64 by init stringa
|
|
|
|
|
|
- replace bb to -- in 256 std::string
|
|
|
|
|
|
- replace bb to -- in 256 lstringa<8>
|
|
|
|
|
|
- replace bb to -- in 256 by init stringa
|
|
|
|
|
|
- replace bb to -- in 512 std::string
|
|
|
|
|
|
- replace bb to -- in 512 lstringa<8>
|
|
|
|
|
|
- replace bb to -- in 512 by init stringa
|
|
|
|
|
|
- replace bb to -- in 1024 std::string
|
|
|
|
|
|
- replace bb to -- in 1024 lstringa<8>
|
|
|
|
|
|
- replace bb to -- in 1024 by init stringa
|
|
|
|
|
|
- replace bb to -- in 2048 std::string
|
|
|
|
|
|
- replace bb to -- in 2048 lstringa<8>
|
|
|
|
|
|
- replace bb to -- in 2048 by init stringa
|
|
|
|
|
|
- hashStrMapA<size_t> emplace & find stringa;
|
|
|
|
|
|
Вставляем в hashStrMapA 10000 stringa длиной от 30 до 50
|
|
|
|
|
|
символов, а потом ищем их в ней
|
2026-01-21 11:59:17 +00:00
|
|
|
|
We insert 10,000 strings of length from 30 to 50 characters into
|
|
|
|
|
|
hashStrMapA, and then search for them in it.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::unordered_map<std::string, size_t> emplace & find std::string;
|
|
|
|
|
|
То же самое c std::string и std::unordered_map
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Same thing with std::string and std::unordered_map
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- hashStrMapA<size_t> emplace & find ssa;
|
|
|
|
|
|
Теперь вставляем stringa, а ищем ssa
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Now we insert stringa and search for ssa
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- std::unordered_map<std::string, size_t> emplace & find std::string_view;
|
|
|
|
|
|
Вставляем std::string, а ищем std::string_view
|
2026-01-21 11:59:17 +00:00
|
|
|
|
We insert std::string and look for std::string_view
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- Build func full name std::string;
|
|
|
|
|
|
Обыденная задача, подобные часто могут встретится в работе:
|
|
|
|
|
|
По неким данным сгенерировать текст. В этом случае по данным
|
|
|
|
|
|
о неких функциях сформировать их полное имя с типами параметров и
|
|
|
|
|
|
возвращаемого значения. Алгоритм на std::string.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
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.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- Build func full name std::string 1;
|
|
|
|
|
|
Почти тот же алгоритм, но несколько последовательных
|
|
|
|
|
|
+= к строке заменены на одно += + + +.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Almost the same algorithm, but several consecutive
|
|
|
|
|
|
+= to a string are replaced with a single += + + +.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- Build func full name std::stream;
|
|
|
|
|
|
Строим имя функции через std::ostringstream и <<
|
2026-01-21 11:59:17 +00:00
|
|
|
|
We construct the function name through std::ostringstream and <<
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- Build func full name stringa;
|
|
|
|
|
|
Реализация на simstr строках и строковых выражениях.
|
|
|
|
|
|
Инфа о параметрах добавляется в текущую строку
|
2026-01-21 11:59:17 +00:00
|
|
|
|
Implementation using simstr strings and string expressions.
|
|
|
|
|
|
Parameter information is appended to the current line.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- Build func full name stringa 1;
|
|
|
|
|
|
Реализация на simstr строках и строковых выражениях.
|
|
|
|
|
|
Инфа о параметрах добавляется во временную строку, а потом
|
|
|
|
|
|
разом добавляется в текущую строку. Позволяет операции в цикле
|
|
|
|
|
|
записать в одну строку, но чуть проигрывает по времени выполнения.
|
2026-01-21 11:59:17 +00:00
|
|
|
|
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.
|
2025-04-05 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
- Пусто
|