Optimized copying of short lstrings.
The Emscripten build now allows benchmarks to run synchronously.
Оптимизировано копирование коротких lstring.
В Emscripten сборке добавлена возможность запустить бенчмарки синхронно.
This commit is contained in:
Aleksandr Orefkov 2026-02-12 19:47:32 +03:00
parent e62493a678
commit ee73896337
21 changed files with 5164 additions and 5138 deletions

View File

@ -5,7 +5,7 @@ include(FetchContent)
project(
simstr
VERSION 1.6.6
VERSION 1.6.7
DESCRIPTION "Yet another modern C++ string library"
HOMEPAGE_URL "https://github.com/orefkov/simstr"
LANGUAGES CXX

View File

@ -1,5 +1,5 @@
/*
* ver. 1.6.6
* ver. 1.6.7
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
* Бенчмарки
* (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com
@ -19,10 +19,13 @@ using namespace std::literals;
#ifdef EMSCRIPTEN
#include <emscripten.h>
bool do_sync = false;
static void DoTeardown(const benchmark::State& state) {
// Это нужно чтобы интерфейс браузера обновился
// This is necessary for the browser interface to refresh.
if (!do_sync) {
emscripten_sleep(1);
}
}
#undef BENCHMARK
#define BENCHMARK(...) \
@ -2466,6 +2469,10 @@ int main(int argc, char** argv) {
#ifdef EMSCRIPTEN
EM_ASM({ console.log(navigator.userAgent); });
if (argc == 2 && stra{argv[1]} == "-sync") {
do_sync = true;
argc = 1;
}
#endif
char arg1[] = "--benchmark_repetitions=4", arg2[] = "--benchmark_report_aggregates_only=true";

View File

@ -147,7 +147,7 @@ However, Windows and Linux are clearly in different weight classes.
- std::string copy{str_with_len_N};/16
Явно виден скачок, где заканчивается SSO и начинается аллокация.
Обратите внимание, что WASM - 32-битный, и там размер
SSO у std::string меньше, насколько я помню, 11 символов + 0.
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.

View File

@ -185,7 +185,7 @@
<body>
<div class="head">
<h3>SimStr 1.6.6 Benchmark</h3>
<h3>SimStr 1.6.7 Benchmark</h3>
<span><a href="https://orefkov.github.io/simstr/results.html" target="blank">All results</a></span>
<span><a href="https://github.com/orefkov/simstr/blob/main/bench/bench_str.cpp" target="blank">Sources for
benchmarks</a></span>
@ -199,25 +199,28 @@
var Module = {
print(...args) {
console.log(...args);
var text = args.join(' ')
try {
if (text.match(/^--+[^-]/)) {
add_benchset(text.match(/^-+ +(.+?) +-+\/repeats/)[1]);
var text = args.join(' ')
var m = text.match(/^--+ +(.+?) +-+\/repeats/);
if (m) {
add_benchset(m[1]);
} else {
var im = text.indexOf("_mean ");
if (im != -1) {
add_benchmark(text.substr(0, im), text.match(/ ([^ ]+?) ns/)[1]);
}
}
outputElement.value += text + "\n";
outputElement.scrollTop = outputElement.scrollHeight;
} catch (e) {
console.error(e);
}
if (outputElement) {
outputElement.value += text + "\n";
outputElement.scrollTop = outputElement.scrollHeight;
}
}
};
var sync = new URLSearchParams(window.location.search).get('sync');
if (sync)
Module.arguments = ["-sync"];
function on_done() {
resultEl.scrollTop = 0;
}

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

@ -48,7 +48,7 @@ PROJECT_NAME = "simstr"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 1.6.6
PROJECT_NUMBER = 1.6.7
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewers a

View File

@ -48,7 +48,7 @@ PROJECT_NAME = "simstr"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 1.6.6
PROJECT_NUMBER = 1.6.7
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewers a

View File

@ -1,6 +1,6 @@
/*
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
* ver. 1.6.6
* ver. 1.6.7
*/
#pragma once

View File

@ -1,5 +1,5 @@
/*
* ver. 1.6.6
* ver. 1.6.7
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
* Классы для работы со строками
* (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com
@ -2661,7 +2661,13 @@ protected:
size_ = newSize;
data_[newSize] = 0;
}
constexpr void copy_from_another(K* buf, const K* src, size_t size) {
// Реальный размер буфера всегда кратен sizeof(void*), поэтому копируя по sizeof(void*) байтов, мы не выйдем за пределы буфера
// The actual buffer size is always a multiple of sizeof(void*), so by copying sizeof(void*) bytes at a time, we won't go beyond the buffer's limits.
size_t need_copy_bytes = (size + 1) * sizeof(K);
size_t cnt = (need_copy_bytes + sizeof(void*) - 1) / sizeof(void*) * sizeof(void*);
traits::copy(buf, src, cnt / sizeof(K));
}
public:
/*!
* @ru @brief Создать пустой объект.
@ -2776,16 +2782,21 @@ public:
* @param other - another string.
*/
constexpr lstring(const my_type& other) : base_storable(other.allocator()) {
if (other.size_) {
K* buf = init(other.size_);
const size_t short_str = 16 / sizeof(K);
if (LocalCapacity >= short_str - 1 && other.size_ < short_str) {
struct copy { char buf[16]; };
*reinterpret_cast<copy*>(buf) = *reinterpret_cast<const copy*>(other.symbols());
} else {
traits::copy(buf, other.symbols(), other.size_ + 1);
struct copy{uint64_t p[2];};
constexpr size_t short_str = sizeof(copy) / sizeof(K);
if constexpr (LocalCapacity >= short_str - 1) {
if (other.size_ < short_str) {
data_ = local_;
size_ = other.size_;
*(copy*)local_ = *(const copy*)other.local_;
return;
}
}
if (size_t size = other.size_) {
copy_from_another(init(size), other.symbols(), size);
} else {
create_empty();
}
}
/*!
* @ru @brief Копирование из другой строки такого же типа, но с другим аллокатором.
@ -2799,7 +2810,9 @@ public:
requires(sizeof...(Args) > 0 && std::is_convertible_v<allocator_t, Args...>)
constexpr lstring(const my_type& other, Args&&... args) : base_storable(std::forward<Args>(args)...) {
if (other.size_) {
traits::copy(init(other.size_), other.symbols(), other.size_ + 1);
copy_from_another(init(other.size_), other.symbols(), other.size_);
} else {
create_empty();
}
}
/*!
@ -2816,10 +2829,11 @@ public:
if constexpr (I > 1) {
K* ptr = init(I - 1);
traits::copy(ptr, (const K*)value, I - 1);
ptr[I - 1] = 0;
} else
ptr[I - 1] = K{};
} else {
create_empty();
}
}
/*!
* @ru @brief Конструктор перемещения из строки такого же типа.
* @param other - другая строка.
@ -2831,14 +2845,16 @@ public:
size_ = other.size_;
if (other.is_alloced()) {
data_ = other.data_;
other.data_ = other.local_;
capacity_ = other.capacity_;
} else {
data_ = local_;
traits::copy(local_, other.local_, size_ + 1);
copy_from_another(data_, other.local_, size_);
}
other.data_ = other.local_;
other.size_ = 0;
other.local_[0] = 0;
} else {
create_empty();
}
}
/*!

View File

@ -1,5 +1,5 @@
/*
* ver. 1.6.6
* ver. 1.6.7
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
* База для строковых конкатенаций через выражения времени компиляции
* (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com

View File

@ -3,7 +3,7 @@
[![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.6.
Version 1.6.7.
<h2>Speed up your work with strings by 2-10 times!</h2>
@ -323,8 +323,8 @@ function(add_simstr)
simstr
GIT_REPOSITORY https://github.com/orefkov/simstr.git
GIT_SHALLOW TRUE
GIT_TAG tags/rel1.6.6 # Specify the desired release
FIND_PACKAGE_ARGS NAMES simstr 1.6.6
GIT_TAG tags/rel1.6.7 # Specify the desired release
FIND_PACKAGE_ARGS NAMES simstr 1.6.7
)
FetchContent_MakeAvailable(simstr)
endfunction()

View File

@ -3,7 +3,7 @@
[![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.6.
Версия 1.6.7.
<h2>Ускорь работу со строками в 2-10 раз!</h2>
@ -323,8 +323,8 @@ function(add_simstr)
simstr
GIT_REPOSITORY https://github.com/orefkov/simstr.git
GIT_SHALLOW TRUE
GIT_TAG tags/rel1.6.6 # Укажите нужный релиз
FIND_PACKAGE_ARGS NAMES simstr 1.6.6
GIT_TAG tags/rel1.6.7 # Укажите нужный релиз
FIND_PACKAGE_ARGS NAMES simstr 1.6.7
)
FetchContent_MakeAvailable(simstr)
endfunction()

View File

@ -1,5 +1,5 @@
/*
* ver. 1.6.6
* ver. 1.6.7
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
* Реализация строковых функций
* (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com

View File

@ -1,5 +1,5 @@
/*
* ver. 1.6.6
* ver. 1.6.7
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
* Тесты simstr
* (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com

View File

@ -1,5 +1,5 @@
/*
* ver. 1.6.6
* ver. 1.6.7
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
* Тесты simstr
* (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com

View File

@ -1,5 +1,5 @@
/*
* ver. 1.6.6
* ver. 1.6.7
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
* Тесты simstr
* (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com