TGViewer
Channel Public Channel
this->notes.

this->notes.

@thisnotes

О разработке, архитектуре и C++.

Tags: #common, #cpp, #highload и другие можно найти поиском.
Задачки: #poll.
Мои публикации: #pub.
Автор и предложка: @vanyakhodor.
GitHub: dasfex.
Subscribers
4.51K
Photos
56
Videos
0
Links
431

Showing posts older than #51 · Back to latest

Older Posts 20 shown
Post #49 307

Forwarded from Peltorator's Channel

Иногда так бывает, что асимптотика решения задачи зависит от количества делителей числа во входе. Когда я только начинал заниматься спортивным программированием, я несколько раз слышал такое утверждение: «количество делителей числа n — это примерно кубический корень из n». И с самого начала я относился к этому факту с подозрением: неужели у чисел может быть так много делителей?

На самом деле, это, конечно, не так, но оценка в кубический корень дает нужный порядок величин для грубых оценок на числах, с которыми мы имеем дело в реальной жизни (отличие не больше, чем в 4 раза при n ≤ 10^15, и не больше, чем в 10 раз при n ≤ 10^18). Давайте разберемся, сколько все таки на самом деле делителей у чисел, и как этим пользоваться, а также придумаем новую более точную оценку.

https://telegra.ph/Ocenka-na-kolichestvo-delitelej-chisla-09-10
Telegraph Оценка на количество делителей числа Предыстория и мотивация Иногда так бывает, что асимптотика решения задачи зависит от количества делителей числа во входе. Когда я только начинал заниматься спортивным программированием, я несколько раз слышал такое утверждение: "количество делителей числа…
Post #46 341
Знание фактов выше позволяет удобно, красиво и единообразно писать операторы копирования/перемещения для ваших классов.
Post #45 365
this->notes. #cpp #poll Предположим, имеем такой код: int x(1); new(&x) int(5); Вызывает ли этот код undefined behaviour? (можно пояснить свой ответ в комментариях 🙂 ) Ответ выложу завтра.
#cpp #stackoverflow

Ответ: нет.

Как и писали в комментариях, могут возникнуть вопросы при использовании объекта, переконструированного на стеке. Однако таких не будет.

Давайте рассмотрим случай not trivially destructible типа. При данном коде деструктор будет вызван лишь единожды, что может привести к утечкам памяти, если класс имеет своими полями некоторые указатели. Потому необходимо сделать явный вызов деструктора, после чего уже можно использовать placement new на это место.

Кто-то скажет, что использование объекта после вызова деструктора по стандарту является неопределённым поведением, но в данном случае мы используем не сам объект, а его storage.

Вот ссылка на вопрос с so, где сообщество поясняло мне за этот случай: https://stackoverflow.com/questions/69062579/is-using-placement-new-with-variable-on-the-stack-is-correct
Stack Overflow Is using placement new with variable on the stack is correct? Let's take a look to this code: A a(123); new(&a) A(124); Test says that in this case when program is shutting down destructor ~A() will called once. So if in A we has some pointers as fields we
Post #42 355
#cpp #poll
Предположим, имеем такой код:

int x(1);
new(&x) int(5);

Вызывает ли этот код undefined behaviour?
(можно пояснить свой ответ в комментариях 🙂 )
Ответ выложу завтра.
Post #40 377
#cpp
Два интересных сервиса:
1. cppinsights.io
Показывает, во что разворачивается ваш код.
2. build-bench.com
Можно померять время компиляции.
Post #36 355

Forwarded from Experimental chill

Когда вы работаете со строками, нередко возникают задачи склеить много строк или просто надобавлять их в конец. Также нередко вы знаете заранее размер финальной строки. И никогда по перформансу невыгодно добавлять строки по одной, в итоге будет достаточно много реаллокаций.

К сожалению, сейчас в С++ нет максимально быстрого способа поджойнить строки, чтобы не платить оверхеда. И по-моему сейчас нет ни в одном языке библиотечной поддержки так делать:

Одни скажут, что можно сделать reserve и сделать append, но тогда append будет каждый раз проверять на то, нужно ли расширять буффер, будет добавлять нулевой байтик в конец, потому что строки в С++ заканчиваются нулевым байтом и будут обновлять размер:

std::string GeneratePattern(const std::string& pattern, size_t count) {
std::string ret;
ret.reserve(pattern.size() * count);
for (size_t i = 0; i < count; i++) {
// SUB-OPTIMAL:
// * Writes 'count' nulls
// * Updates size and checks for potential resize 'count' times
ret.append(pattern);
}
return ret;
}

Другие скажут, что можно сделать resize и потом memcpy, но, к сожалению, resize должен как-то проинициализировать память, поэтому будет лишний memset:

std::string GeneratePattern(const std::string& pattern, size_t count) {
std::string ret;
const auto step = pattern.size();
// SUB-OPTIMAL: We memset step*count bytes
// only to overwrite them.
ret.resize(step * count);
for (size_t i = 0; i < count; i++) {
// GOOD: No bookkeeping
memcpy(ret.data() + i * step, pattern.data(), step);
}
return ret;
}

В итоге стандартные библиотеки имеют незадокументированную функцию __resize_default_init, которая просто аллоцирует сырые неинициализированные байты, в которые можно копировать. Abseil это использует для Join строк, а вот в Яндексе делается reserve и добавляется appendом. Тут винить некого, так просто получилось, что интерфейс "выделить сырую память и проинициализировать тем, чем надо" сложно выражется через обычные примитивы строк.

В C++ на этой неделе, надеюсь, примут в C++23 resize_default_init, который исправляет эту проблему. Синтаксис получается функциональный немного, вызывается callback, который должен заполнять байты выделенной строки, чтобы ни в какой момент времени не оставлять строку неинициализированной, возвращаемое значение отвечает за столько байт, сколько останется в строке в итоге.

ret.resize_default_init(step * count, [&](char* buf, size_t n) {
for (size_t i = 0; i < count; i++) {
// GOOD: No bookkeeping
memcpy(buf + i * step, pattern.data(), step);
}
return step * count; // must be <=n, in that case ==n.
});


[1] P1072 пропозал для стандарта
[2] Abseil resize uninitialized
[3] Abseil join
[4] Yandex join
[5] __resize_default_init в LLVM
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →