- Update benchmarks results.

- Add support for pretty view in debuggers for str_src and str_src_nt.
This commit is contained in:
Aleksandr Orefkov 2026-01-29 23:48:41 +03:00
parent bb70d1b0a4
commit ce3fe2204c
10 changed files with 4777 additions and 4645 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Файл с описанием визуализации simstr строк для Visual Studio --> <!-- Файл с описанием визуализации simstr строк для Visual Studio -->
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="simstr::str_src&lt;*&gt;">
<DisplayString Condition="0xCCCCCCCC==(unsigned)str">[unknown]</DisplayString>
<DisplayString Condition="sizeof($T1)==1">l={len}, {str,[len]nas8}</DisplayString>
<DisplayString Condition="sizeof($T1)==2">l={len}, {str,[len]nasu}</DisplayString>
<DisplayString Condition="sizeof($T1)==4">l={len}, {str,[len]nas32}</DisplayString>
<DisplayString>[unknown]</DisplayString>
</Type>
<Type Name="simstr::str_src_nt&lt;*&gt;">
<DisplayString Condition="0xCCCCCCCC==(unsigned)str">[unknown]</DisplayString>
<DisplayString Condition="sizeof($T1)==1">l={len}, {str,[len]nas8}</DisplayString>
<DisplayString Condition="sizeof($T1)==2">l={len}, {str,[len]nasu}</DisplayString>
<DisplayString Condition="sizeof($T1)==4">l={len}, {str,[len]nas32}</DisplayString>
<DisplayString>[unknown]</DisplayString>
</Type>
<Type Name="simstr::simple_str&lt;*&gt;"> <Type Name="simstr::simple_str&lt;*&gt;">
<DisplayString Condition="0xCCCCCCCC==(unsigned)str">[unknown]</DisplayString> <DisplayString Condition="0xCCCCCCCC==(unsigned)str">[unknown]</DisplayString>
<DisplayString Condition="sizeof($T1)==1">l={len}, {str,[len]nas8}</DisplayString> <DisplayString Condition="sizeof($T1)==1">l={len}, {str,[len]nas8}</DisplayString>
@ -8,6 +22,13 @@
<DisplayString Condition="sizeof($T1)==4">l={len}, {str,[len]nas32}</DisplayString> <DisplayString Condition="sizeof($T1)==4">l={len}, {str,[len]nas32}</DisplayString>
<DisplayString>[unknown]</DisplayString> <DisplayString>[unknown]</DisplayString>
</Type> </Type>
<Type Name="simstr::simple_str_nt&lt;*&gt;">
<DisplayString Condition="0xCCCCCCCC==(unsigned)str">[unknown]</DisplayString>
<DisplayString Condition="sizeof($T1)==1">l={len}, {str,[len]nas8}</DisplayString>
<DisplayString Condition="sizeof($T1)==2">l={len}, {str,[len]nasu}</DisplayString>
<DisplayString Condition="sizeof($T1)==4">l={len}, {str,[len]nas32}</DisplayString>
<DisplayString>[unknown]</DisplayString>
</Type>
<Type Name="simstr::sstring&lt;*&gt;"> <Type Name="simstr::sstring&lt;*&gt;">
<DisplayString Condition="sizeof($T1)==1 &amp;&amp; type_ == 0">inplace, l={LocalCount - localRemain_}, {buf_,[LocalCount - localRemain_]nas8}</DisplayString> <DisplayString Condition="sizeof($T1)==1 &amp;&amp; type_ == 0">inplace, l={LocalCount - localRemain_}, {buf_,[LocalCount - localRemain_]nas8}</DisplayString>
<DisplayString Condition="sizeof($T1)==1 &amp;&amp; type_ == 1">literal, l={bigLen_}, {cstr_,[bigLen_]nas8}</DisplayString> <DisplayString Condition="sizeof($T1)==1 &amp;&amp; type_ == 1">literal, l={bigLen_}, {cstr_,[bigLen_]nas8}</DisplayString>

View File

@ -192,6 +192,8 @@ printer_list = {
"lstring": [lstring_printer, lstring_printer_init], "lstring": [lstring_printer, lstring_printer_init],
"simple_str": [ssa_printer], "simple_str": [ssa_printer],
"simple_str_nt": [ssa_printer], "simple_str_nt": [ssa_printer],
"str_src": [ssa_printer],
"str_src_nt": [ssa_printer],
} }
for name, func in printer_list.items(): for name, func in printer_list.items():

139
readme.md
View File

@ -1,19 +1,23 @@
# simstr - String object and function library # simstr - String Object and Function Library
<h2>Speed up your work with strings by 2-10 times!</h2> <span class="obfuscator"><a href="readme_ru.md">Russian | По-русски</a></span>
[![CMake on multiple platforms](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml) [![CMake on multiple platforms](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml)
Version 1.6.0. Version 1.6.0.
<span class="obfuscator"><a href="readme_ru.md">On Russian | По-русски</a></span> <h2>Speed up your work with strings by 2-10 times!</h2>
This library contains a modern implementation of several types of string objects and various algorithms for working with strings. This library contains a modern implementation of several types of string objects and various algorithms for working with strings.
## Generated Documentation
[Located here](https://orefkov.github.io/simstr/docs_ru/)
## Brief Description
The goal of the library is to make working with strings in C++ as simple and easy as in many other languages, especially The goal of the library is to make working with strings in C++ as simple and easy as in many other languages, especially
scripting languages, while maintaining optimal performance at the level of C and C++, and even improving them. scripting languages, while maintaining optimality and performance at the level of C and C++, and even improving them.
It's no secret that working with strings in C++ often causes pain. The `std::string` class is often inconvenient or inefficient. It's no secret that working with strings in C++ often causes pain. The `std::string` class is often inconvenient or inefficient.
Many functions that are usually needed when working with strings are simply not there, and everyone has to write them themselves. Many functions that are usually necessary when working with strings are simply not there, and everyone has to write them themselves.
Even concatenating `std::string` and `std::string_view` became possible only with C++26. Even concatenating `std::string` and `std::string_view` became possible only with C++26.
That's why I started creating this library for myself around 2012, and now I'm ready to share it with all C++ developers. That's why I started creating this library for myself around 2012, and now I'm ready to share it with all C++ developers.
@ -22,19 +26,19 @@ use in my work, trying to do it in the most efficient way, and I modestly hope t
and will be useful to other people, either directly or as a source of ideas. and will be useful to other people, either directly or as a source of ideas.
The library contains two parts: The library contains two parts:
- Implementation of [*"String Expressions"*](https://orefkov.github.io/simstr/docs_en/overview.html#autotoc_md68) and algorithms for working - Implementation of [*"String Expressions"*](https://orefkov.github.io/simstr/docs_ru/overview.html#autotoc_md27) and algorithms for working
with constant strings.\ with constant strings.\
To use this part, just take the file `"include/simstr/strexpr.h"` and write in your code To use this part, just take the file `"include/simstr/strexpr.h"` and write in your code
```cpp ```cpp
#include "path/to/file/strexpr.h" #include "путь/к файлу/strexpr.h"
``` ```
This will allow you to use powerful and fast *"string expressions"* for concatenation and string construction for standard string types (`std::basic_string`, `std::basic_string_view`), as well as simplified versions of the `simple_str` and This will allow you to use powerful and fast *"string expressions"* for concatenation and string construction for standard string types (`std::basic_string`, `std::basic_string_view`), as well as simplified versions of the `simple_str` and
`simple_str_nt` classes, which implement all those string algorithms of the library that do not require storing or modifying strings. `simple_str_nt` classes, which implement all those string algorithms of the library that do not require storing or modifying strings.
Since this is a header-only part, it does not include working with UTF encodings and simplified Unicode. Since this is a header-only part, it does not include working with UTF encodings and simplified Unicode.
- The full version, which requires connecting the entire library (`"include/simstr/sstring.h"`), adds its own string types with - The full version, requiring the connection of the entire library (`"include/simstr/sstring.h"`), adds its string types with
the ability to store and modify strings, works with UTF encodings and simplified Unicode. the ability to store and modify strings, works with UTF encodings and simplified Unicode.
The library does not pretend to be "changed the header and everything worked better" - it gets along well with standard strings The library does not pretend to be a "changed header and everything worked better" - it gets along well with standard strings
and does not change the behavior of existing code working with them. I tried to make many methods in it compatible and does not change the behavior of existing code working with them. I tried to make many methods in it compatible
with `std::string` and `std::string_view`, but I didn't bother with this much. Rewriting your code to work with `simstr` with `std::string` and `std::string_view`, but I didn't bother with this much. Rewriting your code to work with `simstr`
will require some effort, but I assure you that it will pay off. And thanks to compatibility with standard strings, this work can be done will require some effort, but I assure you that it will pay off. And thanks to compatibility with standard strings, this work can be done
@ -46,14 +50,14 @@ types of objects, each of which is good for its own purposes, and at the same ti
If you actively used `std::string_view` and understood its advantages and disadvantages compared to `std::string`, If you actively used `std::string_view` and understood its advantages and disadvantages compared to `std::string`,
then the `simstr` approach will also be clear to you. then the `simstr` approach will also be clear to you.
## Main features of the library ## Key Features of the Library
When using only `#include "simstr/strexpr.h"`: When using only `#include "simstr/strexpr.h"`:
- Support for working with strings `char`, `char8_t`, `char16_t`, `char32_t`, `wchar_t`. - Support for working with strings `char`, `char8_t`, `char16_t`, `char32_t`, `wchar_t`.
- Powerful and extensible *"String Expressions"* system. - Powerful and extensible *"String Expressions"* system.
Allows you to efficiently implement the conversion and addition (concatenation) of strings, string literals, numbers (and possibly other objects), Allows you to efficiently implement the conversion and addition (concatenation) of strings, string literals, numbers (and possibly other objects),
achieving significant acceleration of string operations. achieving significant acceleration of string operations.
Compatible with both `simstr` string objects and standard strings (`std::basic_string`, Compatible with both `simstr` string objects and standard strings (`std::basic_string`,
`std::basic_string_view`), which allows you to use fast concatenation even where it is not yet possible to abandon standard strings. `std::basic_string_view`), which allows you to apply fast concatenation even where it is not yet possible to abandon standard strings.
Also allows you to mix strings of compatible character types in operations. Also allows you to mix strings of compatible character types in operations.
- Constant string functions (do not change the original string): - Constant string functions (do not change the original string):
- Getting substrings. - Getting substrings.
@ -62,17 +66,17 @@ When using only `#include "simstr/strexpr.h"`:
- Various trimming of strings - right, left, everywhere, by whitespace characters, by specified characters. - Various trimming of strings - right, left, everywhere, by whitespace characters, by specified characters.
- Replacing substrings (creating a copy of the string with the replacement). - Replacing substrings (creating a copy of the string with the replacement).
- Replacing a set of characters with a set of corresponding substrings (creating a copy of the string with the replacement). - Replacing a set of characters with a set of corresponding substrings (creating a copy of the string with the replacement).
- Merging (join) containers of strings into a single string, with specifying delimiters and options - "skip empty", "delimiter after last". - Merging (join) containers of strings into a single string, with specifying separators and options - "skip empty", "separator after last".
- Splitting strings into parts by a specified delimiter. Splitting is possible immediately into a container with strings, or by calling a functor for - Splitting strings into parts by a specified delimiter. Splitting is possible immediately into a container with strings, or by calling a functor for
each substring, or by iterating using the `Splitter` iterator. each substring, or by iterating using the `Splitter` iterator.
- Functions for modifying standard strings with string expressions: - Functions for modifying standard strings with string expressions:
- str::append, str::prepend, str::insert, str::change - modify str::string with string expressions, - str::append, str::prepend, str::insert, str::change - change str::string with string expressions,
for example, `str::append(text, "count = "_ss + count + " times")`. for example `str::append(text, "count = "_ss + count)`.
- str::replace - replaces occurrences of the searched substring with the replacement string or string expression. - str::replace - replaces occurrences of the search substring with a replacement string or string expression.
If the substring is not found, the string expression is not even evaluated. If the substring is not found, the string expression is not even evaluated.
- Parsing integers with the possibility of "fine" tuning at compile time - you can set options for checking overflow, - Parsing integers with the possibility of "fine" tuning at compile time - you can set options for checking overflow,
skipping whitespace characters, a specific base or auto-selection by prefixes `0x`, `0`, `0b`, `0o`, skipping whitespace characters, a specific radix or auto-selection by prefixes `0x`, `0`, `0b`, `0o`,
admissibility of the `+` sign. Parsing is implemented for all types of strings and characters. the admissibility of the `+` sign. Parsing is implemented for all types of strings and characters.
- Parsing double for `char` and `wchar_t`, as well as character types compatible with them in size. - Parsing double for `char` and `wchar_t`, as well as character types compatible with them in size.
When using the full version of the library: When using the full version of the library:
@ -91,27 +95,43 @@ When using the full version of the library:
Works only for characters of the first Unicode plane (up to 0xFFFF), and when changing the case, cases are not taken into account when one code point Works only for characters of the first Unicode plane (up to 0xFFFF), and when changing the case, cases are not taken into account when one code point
can be converted into several, that is, the case conversion of characters corresponds to `std::towupper`, `std::towlower` for the unicode locale, only faster and can work with any type of characters. can be converted into several, that is, the case conversion of characters corresponds to `std::towupper`, `std::towlower` for the unicode locale, only faster and can work with any type of characters.
- Implemented `hash map` for string type keys, based on `std::unordered_map`, with the possibility of more efficient storage and - Implemented `hash map` for string type keys, based on `std::unordered_map`, with the possibility of more efficient storage and
comparison of keys compared to `std::string` keys. The possibility of case-insensitive comparison of keys is supported (Ascii or comparison of keys compared to `std::string` keys. Supports the possibility of case-insensitive comparison of keys (Ascii or
minimal Unicode (see previous paragraph)). minimal Unicode (see previous paragraph)).
## String expressions ## Benchmarks
Benchmarks are performed using the [Google benchmark](https://github.com/google/benchmark) framework.
I tried to make measurements for the most typical operations that occur in normal work. I took measurements on my equipment, under
Windows and Linux (in WSL), using MSVC, Clang, GCC compilers. Third-party results are welcome.
I also took measurements in WASM, built in Emscripten. I draw attention to the fact that a 32-bit build is built under WASM in Emscripten, which means that
the sizes of SSO buffers in objects are smaller.
On the [release page](https://github.com/orefkov/simstr/releases) you can download binary builds of benchmarks and run them on your equipment.
You can also run the [Emscripten build of benchmarks](https://orefkov.github.io/simstr/bench/benchStr.html) directly in the browser.
(Before following the link, it is better to open "Developer Tools" (usually **F12**) in advance to see the console
Javascript, since the page will not be updated until the benchmarks are completed, and all output will be visible in the console).
- [Benchmark source code](bench/bench_str.cpp)
- [Benchmark results](https://orefkov.github.io/simstr/results.html)
## String Expressions
These are special objects that efficiently implement string concatenation using `operator+`. These are special objects that efficiently implement string concatenation using `operator+`.
The main principle, due to which efficient work is achieved - no matter how many operands are included in the entire expression, The main principle, due to which efficient work is achieved - no matter how many operands are included in the entire expression,
no temporary (intermediate) strings are created, the total length of the entire result is calculated only once, no temporary (intermediate) strings are created, the total length of the entire result is calculated only once,
memory is allocated for the character buffer of the result only once, after which the characters are copied immediately to the buffer of the result memory is allocated for the result character buffer only once, after which the characters are copied directly to the result buffer
to its place. No memory reallocations, no moving characters in various intermediate buffers - everything is to its place. No memory reallocations, no moving characters in various intermediate buffers - everything is
as efficient as possible. Thanks to the capabilities of C++ templates and operator overloading, the expression is written as close as possible as efficient as possible. Thanks to the capabilities of C++ templates and operator overloading, the expression is written as close as possible
to the usual string addition syntax. to the usual syntax for adding strings.
In addition, there are special overloads for adding string objects and string literals, strings and numbers, In addition, there are special overloads for adding string objects and string literals, strings and numbers,
for copying with replacement, for merging containers of strings and much more. for copying with replacement, for merging containers of strings and much more.
Thanks to the extensibility of this system, it is possible to create new options for building strings, development is constantly ongoing. Thanks to the extensibility of this system, it is possible to create new options for building strings, and development is constantly ongoing.
All string objects from `simstr` are themselves string expressions, that is, they can be used in concatenation operations All string objects from `simstr` are themselves string expressions, that is, they can be used in concatenation operations
of string expressions directly. Standard strings (`std::basic_string`, `std::basic_string_view`) can also serve as operands string expressions directly. Standard strings (`std::basic_string`, `std::basic_string_view`) can also serve as operands
in addition operations with string expressions. Or they can be easily converted into a string expression by placing a in addition operations with string expressions. Or they can be easily converted into a string expression by placing them in front of them
unary `+` in front of them. unary `+`.
## Usage examples ## Usage Examples
### Adding strings with numbers ### Adding strings with numbers
```cpp ```cpp
std::string s1 = "start "; std::string s1 = "start ";
@ -122,9 +142,9 @@ int i;
// Became // Became
std::string str = +s1 + i + " end"; std::string str = +s1 + i + " end";
``` ```
`+s1` - converts `std::string` into an object - a string expression, for which there is an efficient concatenation with numbers and string literals. `+s1` - converts `std::string` into an object - a string expression for which there is an efficient concatenation with numbers and string literals.
According to benchmarks, [acceleration is 1.6 - 2 times](https://orefkov.github.io/simstr/results.html#bs70109915512075798510). According to benchmarks, [acceleration 1.6 - 2 times](https://orefkov.github.io/simstr/results.html#bs70109915512075798510).
### Adding strings with numbers in hex format ### Adding strings with numbers in hex format
```cpp ```cpp
@ -134,7 +154,7 @@ According to benchmarks, [acceleration is 1.6 - 2 times](https://orefkov.github.
// Became // Became
std::string str = +s1 + e_hex<HexFlags::Short>(i) + " end"; std::string str = +s1 + e_hex<HexFlags::Short>(i) + " end";
``` ```
Acceleration in [**9 - 14 times!!!**](https://orefkov.github.io/simstr/results.html#bs146911715078927772520) Acceleration by [**9 - 14 times!!!**](https://orefkov.github.io/simstr/results.html#bs146911715078927772520)
### Adding multiple literals and searching in `std::string_view` ### Adding multiple literals and searching in `std::string_view`
```cpp ```cpp
@ -151,17 +171,17 @@ size_t find_pos(ssa src, ssa name) {
// And when using the full library, you can do this // And when using the full library, you can do this
size_t find_pos(ssa src, ssa name) { size_t find_pos(ssa src, ssa name) {
// In this version, if the result of the concatenation fits into 207 characters, it is produced in a buffer on the stack, // In this version, if the result of the concatenation fits into 207 characters, it is produced in a buffer on the stack,
// without allocation and deallocation of memory, acceleration is several times. And only if the result is longer than 207 characters - // without allocation and deallocation of memory, acceleration several times. And only if the result is longer than 207 characters -
// there will be only one allocation, and the concatenation will be immediately into the allocated buffer, without copying characters. // there will be only one allocation, and the concatenation will be immediately into the allocated buffer, without copying characters.
return src.find(lstringa<200>{"\n- " + name + " -\n"}); return src.find(lstringa<200>{"\n- " + name + " -\n"});
} }
``` ```
`ssa` - alias for `simple_str<char>` - analogue of `std::string_view`, allows you to accept any string object as a function parameter with minimal costs, `ssa` - alias for `simple_str<char>` - analogue of `std::string_view`, allows you to accept as a function parameter with minimal costs
which does not need to be modified or passed to the C-API: `std::string`, `std::string_view`, `"string literal"`, any string object that does not need to be modified or passed to the C-API: `std::string`, `std::string_view`, `"string literal"`,
`simple_str_nt`, `sstring`, `lstring`. Also, since it is also a "string expression", it allows you to easily `simple_str_nt`, `sstring`, `lstring`. Also, since it is also a "string expression", it allows you to easily
build concatenations with its participation. build concatenations with its participation.
According to measurements, [acceleration is 1.5 - 9 times](https://orefkov.github.io/simstr/results.html#bs68116594352702954700). According to measurements, [acceleration 1.5 - 9 times](https://orefkov.github.io/simstr/results.html#bs68116594352702954700).
### Addition with conditions ### Addition with conditions
```cpp ```cpp
@ -188,7 +208,7 @@ std::string buildTypeName(std::string_view type_name, size_t prec, size_t scale)
// Became when using only strexpr.h and simple_str string // Became when using only strexpr.h and simple_str string
std::string buildTypeName(ssa type_name, size_t prec, size_t scale) { std::string buildTypeName(ssa type_name, size_t prec, size_t scale) {
if (prec) { if (prec) {
// ssa is already a string expression, + before it is not needed // ssa is already a string expression, + in front of it is not needed
return type_name + "(" + prec + e_if(scale, ","_ss + scale) + ")"; return type_name + "(" + prec + e_if(scale, ","_ss + scale) + ")";
} }
return type_name; return type_name;
@ -201,7 +221,7 @@ stringa buildTypeName(ssa type_name, size_t prec, size_t scale) {
return type_name; return type_name;
} }
``` ```
When `prec != 0`, [acceleration is 1.5 - 2.2 times](https://orefkov.github.io/simstr/results.html#bs145290966789248325200). When `prec != 0`, [acceleration 1.5 - 2.2 times](https://orefkov.github.io/simstr/results.html#bs145290966789248325200).
### Addition with replacements ### Addition with replacements
```cpp ```cpp
@ -257,32 +277,33 @@ int split_and_calc_total_sim(ssa numbers, ssa delimiter) {
return total; return total;
} }
``` ```
[Acceleration in 2-3 times](https://orefkov.github.io/simstr/results.html#bs7106975351756760120). [Acceleration by 2-3 times](https://orefkov.github.io/simstr/results.html#bs7106975351756760120).
In addition to the individual examples given here, you can look at the sources: In addition to the individual examples given here, you can look at the sources:
- [tests of the entire library](https://github.com/orefkov/simstr/blob/main/tests/test_str.cpp) - [tests of the entire library](https://github.com/orefkov/simstr/blob/main/tests/test_str.cpp)
- [tests of only the strexpr part](https://github.com/orefkov/simstr/blob/main/tests/test_expr_only.cpp) - [tests of only the strexpr part](https://github.com/orefkov/simstr/blob/main/tests/test_expr_only.cpp)
- [examples of using your types in string expressions](https://github.com/orefkov/simstr/blob/main/tests/test_tostrexpr.cpp)
- [benchmarks](https://github.com/orefkov/simstr/blob/main/bench/bench_str.cpp) - [benchmarks](https://github.com/orefkov/simstr/blob/main/bench/bench_str.cpp)
- [utility for preparing html](https://github.com/orefkov/simstr/blob/main/bench/process_result.cpp) from benchmark results. - [utility for preparing html](https://github.com/orefkov/simstr/blob/main/bench/process_result.cpp) from benchmark results.
## Main objects of the library ## Main Objects of the Library
Available with any use: Available with any use:
- `simple_str<K>` - the simplest string (or piece of string), immutable, not owning, analogue of `std::string_view`. - `simple_str<K>` - the simplest string (or piece of string), immutable, not owning, analogue of `std::string_view`.
- `simple_str_nt<K>` - the same, only declares that it ends with 0. For working with third-party C-API. - `simple_str_nt<K>` - the same, only declares that it ends with 0. For working with third-party C-API.
Available when using the entire library: Available when using the entire library:
- `sstring<K>` - shared string, immutable, owning, with shared character buffer, SSO support. - `sstring<K>` - shared string, immutable, owning, with a shared character buffer, SSO support.
- `lstring<K, N>` - local string, mutable, owning, with a specified size of the SSO buffer. - `lstring<K, N>` - local string, mutable, owning, with a specified size of the SSO buffer.
When connecting only `strexpr.h` - the types `simple_str<K>` and `simple_str_nt<K>` do not contain methods for working with UTF and Unicode. When connecting only `strexpr.h` - the types `simple_str<K>` and `simple_str_nt<K>` do not contain methods for working with UTF and Unicode.
## Articles ## Articles
- [Overview and introduction](docs/overview.md) - [Overview and introduction](docs/overview.md)
- [Overview article on Habr](https://habr.com/ru/articles/935590) (On Russian) - [Overview article on Habr](https://habr.com/ru/articles/935590) (on Russian)
- [Description of the "Expression Templates" technique used](https://habr.com/ru/articles/936468/) (On Russian) - [Description of the applied technique "Expression Templates"](https://habr.com/ru/articles/936468/)(on Russian)
## Usage ## Usage
The library can be used partially, just by taking the file `"include/simstr/strexpr.h"` and including it in your sources The library can be used partially, simply by taking the file `"include/simstr/strexpr.h"` and including it in your sources
```cpp ```cpp
#include "include/simstr/strexpr.h" #include "include/simstr/strexpr.h"
``` ```
@ -293,7 +314,7 @@ You can connect as a CMake project via `add_subdirectory` (the `simstr` library)
you can simply include the files in your project. Building also requires [simdutf](https://github.com/simdutf/simdutf) (when using CMake you can simply include the files in your project. Building also requires [simdutf](https://github.com/simdutf/simdutf) (when using CMake
it is downloaded automatically). it is downloaded automatically).
### Using FetchContent ### Connection via FetchContent
``` ```
function(add_simstr) function(add_simstr)
set(SIMSTR_BUILD_TESTS OFF) set(SIMSTR_BUILD_TESTS OFF)
@ -302,7 +323,7 @@ function(add_simstr)
simstr simstr
GIT_REPOSITORY https://github.com/orefkov/simstr.git GIT_REPOSITORY https://github.com/orefkov/simstr.git
GIT_SHALLOW TRUE GIT_SHALLOW TRUE
GIT_TAG tags/rel1.6.0 # Укажите нужный релиз GIT_TAG tags/rel1.6.0 # Specify the desired release
FIND_PACKAGE_ARGS NAMES simstr 1.6.0 FIND_PACKAGE_ARGS NAMES simstr 1.6.0
) )
FetchContent_MakeAvailable(simstr) FetchContent_MakeAvailable(simstr)
@ -315,31 +336,17 @@ target_link_libraries(<your target> PUBLIC simstr::simstr)
The library is also included in [vcpkg](https://vcpkg.io), connected as `orefkov-simstr`. The library is also included in [vcpkg](https://vcpkg.io), connected as `orefkov-simstr`.
`simstr` requires a compiler of at least the C++20 standard - concepts and std::format are used. For `simstr` to work, a compiler of the standard no lower than C++20 is required - concepts and std::format are used.
The work was tested under Windows on MSVC-19 and Clang-19, under Linux - on GCC-13 and Clang-21. The work was checked under Windows on MSVC-19 and Clang-19, under Linux - on GCC-13 and Clang-21.
The work in WASM was also tested, built in Emscripten 4.0.6, Clang-21. The work in WASM was also checked, built in Emscripten 4.0.6, Clang-21.
## Convenient Debugging
## Convenient debugging Along with the library, two files are supplied that make viewing simstr string objects in debuggers
Together with the library, two files are supplied that make viewing simstr string objects in debuggers
more convenient.\ more convenient.\
More details are described [here](for_debug/readme_ru.md). More details are described [here](for_debug/readme_ru.md).
## Benchmarks ## Where it is already used
Benchmarks are performed using the [Google benchmark](https://github.com/google/benchmark) framework. Simstr is also used in my projects:
I tried to take measurements for the most typical operations that occur in normal work. I took measurements on my equipment, under
Windows and Linux (in WSL), using MSVC, Clang, GCC compilers. Third-party results are welcome.
I also took measurements in WASM, built in Emscripten. I draw your attention to the fact that a 32-bit build is assembled under WASM in Emscripten, which means that
the sizes of SSO buffers in objects are smaller.
- [Source code of benchmarks](bench/bench_str.cpp)
- [Benchmark results](https://orefkov.github.io/simstr/results.html)
Also, simstr is used in my projects:
- [simjson](https://github.com/orefkov/simjson) - a library for simple work with JSON using simstr strings. - [simjson](https://github.com/orefkov/simjson) - a library for simple work with JSON using simstr strings.
- [simrex](https://github.com/orefkov/simrex) - wrapper for working with regular expressions [Oniguruma](https://github.com/kkos/oniguruma) using simstr strings. - [simrex](https://github.com/orefkov/simrex) - a wrapper for working with regular expressions [Oniguruma](https://github.com/kkos/oniguruma) using simstr strings.
- [v8sqlite](https://github.com/orefkov/v8sqlite) - external component for 1C-Enterprise V8 for working with sqlite. - [v8sqlite](https://github.com/orefkov/v8sqlite) - an external component for 1C-Enterprise V8 for working with sqlite.
## Generated documentation
[Located here](https://orefkov.github.io/simstr/docs_en/)

View File

@ -1,14 +1,18 @@
# simstr - библиотека строковых объектов и функций # simstr - библиотека строковых объектов и функций
<h2>Ускорь работу со строками в 2-10 раз!</h2> <span class="obfuscator"><a href="readme.md">On English | По-английски</a></span>
[![CMake on multiple platforms](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml) [![CMake on multiple platforms](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml)
Версия 1.6.0. Версия 1.6.0.
<span class="obfuscator"><a href="readme.md">On English | По-английски</a></span> <h2>Ускорь работу со строками в 2-10 раз!</h2>
В этой библиотеке содержится современная реализация нескольких видов строковых объектов и различных алгоритмов для работы со строками. В этой библиотеке содержится современная реализация нескольких видов строковых объектов и различных алгоритмов для работы со строками.
## Сгенерированная документация
[Находится здесь](https://orefkov.github.io/simstr/docs_ru/)
## Краткое описание
Цель библиотеки - сделать работу со строками в С++ такой же простой и лёгкой, как во множестве других языков, особенно Цель библиотеки - сделать работу со строками в С++ такой же простой и лёгкой, как во множестве других языков, особенно
скриптовых, но при этом сохранив оптимальность и производительность на уровне С и C++, и даже улучшив их. скриптовых, но при этом сохранив оптимальность и производительность на уровне С и C++, и даже улучшив их.
@ -95,6 +99,22 @@
сравнения ключей по сравнению с ключами `std::string`. Поддерживается возможность регистро-независимого сравнения ключей (Ascii или сравнения ключей по сравнению с ключами `std::string`. Поддерживается возможность регистро-независимого сравнения ключей (Ascii или
минимальный Unicode (см. предыдущий пункт)). минимальный Unicode (см. предыдущий пункт)).
## Бенчмарки
Бенчмарки производятся с использованием фреймворка [Google benchmark](https://github.com/google/benchmark).
Постарался сделать замеры для наиболее типичных операций, встречающихся в обычной работе. Я проводил замеры на своём оборудовании, под
Windows и Linux (в WSL), с использованием компиляторов MSVC, Clang, GCC. Сторонние результаты приветствуются.
Также проводил замеры в WASM, сборка в Emscripten. Обращаю внимание, что под WASM в Emscripten собирается 32-битная сборка, а значит,
размеры буферов SSO в объектах меньше.
На [странице релизов](https://github.com/orefkov/simstr/releases) вы можете скачать бинарные сборки бенчмарков и запустить их на своём оборудовании.
Также вы можете запустить [Emscripten сборку бенчмарков](https://orefkov.github.io/simstr/bench/benchStr.html) прямо в браузере.
(Перед переходом по ссылке лучше предварительно откройте "Инструменты разработчика" (обычно **F12**), чтобы видеть консоль
Javascript, так как до окончания бенчмарков страница не будет обновляться, а весь вывод будет виден в консоли).
- [Исходный код бенчмарков](bench/bench_str.cpp)
- [Результаты бенчмарков](https://orefkov.github.io/simstr/results.html)
## Строковые выражения ## Строковые выражения
Это специальные объекты, которые эффективно реализуют конкатенацию строк, с помощью `operator+`. Это специальные объекты, которые эффективно реализуют конкатенацию строк, с помощью `operator+`.
Главный принцип, за счёт которого достигается эффективная работа - сколько бы операндов не входило во всё выражение, Главный принцип, за счёт которого достигается эффективная работа - сколько бы операндов не входило во всё выражение,
@ -263,6 +283,7 @@ int split_and_calc_total_sim(ssa numbers, ssa delimiter) {
Помимо приведённых здесь отдельных примеров, можно посмотреть исходники: Помимо приведённых здесь отдельных примеров, можно посмотреть исходники:
- [тестов всей библиотеки](https://github.com/orefkov/simstr/blob/main/tests/test_str.cpp) - [тестов всей библиотеки](https://github.com/orefkov/simstr/blob/main/tests/test_str.cpp)
- [тестов только strexpr части](https://github.com/orefkov/simstr/blob/main/tests/test_expr_only.cpp) - [тестов только strexpr части](https://github.com/orefkov/simstr/blob/main/tests/test_expr_only.cpp)
- [примеры использования своих типов в строковых выражениях](https://github.com/orefkov/simstr/blob/main/tests/test_tostrexpr.cpp)
- [бенчмарков](https://github.com/orefkov/simstr/blob/main/bench/bench_str.cpp) - [бенчмарков](https://github.com/orefkov/simstr/blob/main/bench/bench_str.cpp)
- [утилиты подготовки html](https://github.com/orefkov/simstr/blob/main/bench/process_result.cpp) из результатов бенчмарков. - [утилиты подготовки html](https://github.com/orefkov/simstr/blob/main/bench/process_result.cpp) из результатов бенчмарков.
@ -320,27 +341,13 @@ target_link_libraries(<your target> PUBLIC simstr::simstr)
Работа проверялась под Windows на MSVC-19 и Clang-19, под Linux - на GCC-13 и Clang-21. Работа проверялась под Windows на MSVC-19 и Clang-19, под Linux - на GCC-13 и Clang-21.
Также проверялась работа в WASM, сборка в Emscripten 4.0.6, Clang-21. Также проверялась работа в WASM, сборка в Emscripten 4.0.6, Clang-21.
## Удобная отладка ## Удобная отладка
Вместе с библиотекой поставляются два файла, делающие просмотр simstr строковых объектов в отладчиках Вместе с библиотекой поставляются два файла, делающие просмотр simstr строковых объектов в отладчиках
более удобным.\ более удобным.\
Более подробно описано [здесь](for_debug/readme_ru.md). Более подробно описано [здесь](for_debug/readme_ru.md).
## Бенчмарки ## Где уже используется
Бенчмарки производятся с использованием фреймворка [Google benchmark](https://github.com/google/benchmark).
Постарался сделать замеры для наиболее типичных операций, встречающихся в обычной работе. Я проводил замеры на своём оборудовании, под
Windows и Linux (в WSL), с использованием компиляторов MSVC, Clang, GCC. Сторонние результаты приветствуются.
Также проводил замеры в WASM, сборка в Emscripten. Обращаю внимание, что под WASM в Emscripten собирается 32-битная сборка, а значит,
размеры буферов SSO в объектах меньше.
- [Исходный код бенчмарков](bench/bench_str.cpp)
- [Результаты бенчмарков](https://orefkov.github.io/simstr/results.html)
Также simstr используется в моих проектах: Также simstr используется в моих проектах:
- [simjson](https://github.com/orefkov/simjson) - библиотека для простой работы с JSON с использованием строк simstr. - [simjson](https://github.com/orefkov/simjson) - библиотека для простой работы с JSON с использованием строк simstr.
- [simrex](https://github.com/orefkov/simrex) - обёртка для работы с регулярными выражениями [Oniguruma](https://github.com/kkos/oniguruma) с использованием строк simstr. - [simrex](https://github.com/orefkov/simrex) - обёртка для работы с регулярными выражениями [Oniguruma](https://github.com/kkos/oniguruma) с использованием строк simstr.
- [v8sqlite](https://github.com/orefkov/v8sqlite) - внешняя компонента для 1С-Предприятия V8 для работы с sqlite. - [v8sqlite](https://github.com/orefkov/v8sqlite) - внешняя компонента для 1С-Предприятия V8 для работы с sqlite.
## Сгенерированная документация
[Находится здесь](https://orefkov.github.io/simstr/docs_ru/)