Гайд Виды повышение производительности C++ приложений

Участник
Статус
Оффлайн
Регистрация
19 Апр 2020
Сообщения
1,169
Реакции[?]
313
Поинты[?]
151K
1. Используйте эффективные структуры данных.
Пример: При работе с большими объемами данных, выбирайте структуры данных, оптимальные с точки зрения доступа и изменения данных.
C++:
#include <vector>
#include <map>

int main() {
    // Использование эффективных контейнеров STL
    std::vector<int> vec; // для последовательного доступа
    std::map<int, std::string> myMap; // для быстрого поиска по ключу
    return 0;
}
2. Оптимизация циклов.
Пример: Используйте префиксные операции вместо постфиксных, если это возможно, для уменьшения затрат.


C++:
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // Плохо: использует постфиксный инкремент
    for (int i = 0; i < vec.size(); i++) {
        // делать что-то
    }

    // Хорошо: использует префиксный инкремент
    for (int i = 0; i < vec.size(); ++i) {
        // делать что-то
    }

    return 0;
}

3. Используйте ссылки вместо копирования.
Пример: Передавайте объекты по ссылке, чтобы избежать лишних копирований.


C++:
#include <vector>
#include <iostream>

// Плохо: передача вектора по значению
void processVector(std::vector<int> data) {
    // делать что-то
}

// Хорошо: передача вектора по ссылке
void processVectorEfficiently(const std::vector<int>& data) {
    // делать что-то
}

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    processVector(vec); // Плохо
    processVectorEfficiently(vec); // Хорошо
    return 0;
}

4. Используйте многопоточность.
Пример: Разбейте задачи на потоки для более эффективного использования многопроцессорных систем.


C++:
#include <iostream>
#include <thread>
#include <vector>

// Функция, выполняемая в потоке
void processChunk(const std::vector<int>& chunk) {
    // обработка куска данных
}

int main() {
    std::vector<int> data = { /* большой массив данных */ };
    const int numThreads = 4;

    // Разбиваем данные на куски и обрабатываем параллельно
    std::vector<std::thread> threads;
    size_t chunkSize = data.size() / numThreads;
    for (int i = 0; i < numThreads; ++i) {
        auto start = data.begin() + i * chunkSize;
        auto end = (i == numThreads - 1) ? data.end() : start + chunkSize;
        threads.emplace_back(processChunk, std::vector<int>(start, end));
    }

    // Дожидаемся завершения всех потоков
    for (auto& thread : threads) {
        thread.join();
    }

    return 0;
}
задавайте вопросы, отвечу.
так-же можете предложить свои улучшения, добавлю.
с наступающим всех)​
 
ставь чайник, зажигай плиту
Эксперт
Статус
Оффлайн
Регистрация
22 Май 2020
Сообщения
1,444
Реакции[?]
1,092
Поинты[?]
10K
Разработчик
Статус
Оффлайн
Регистрация
18 Мар 2020
Сообщения
438
Реакции[?]
869
Поинты[?]
194K
Пример: Используйте префиксные операции вместо постфиксных, если это возможно, для уменьшения затрат.
А вы знали, что если использовать префиксный инкремент вместо постфиксного, то компилятору будет похуй?
 
rgb(24, 205, 154)
Пользователь
Статус
Оффлайн
Регистрация
9 Фев 2019
Сообщения
288
Реакции[?]
80
Поинты[?]
75K
Только всё, что тут описано знаешь спп-шник, который писал что-то сложнее, чем "Hello, World!"
 
c:\buildworker\csgo_rel_win64
Участник
Статус
Оффлайн
Регистрация
18 Окт 2022
Сообщения
600
Реакции[?]
212
Поинты[?]
140K
Хорошая кликбайтовская тема, не ведитесь, сейчас под любым предлогом очкарики пытаются втюхать своё модерн с++ std под видом новшевства который якобы работает супер быстро классно и тд и тп, да может это и так, но это никак не заменяет того факта что основа основ всему классический C и с++ и когда ты напишешь шаблоны и все эти std приколы потом не создавай топики со скрином визуалки ака почему не работает. лучше классический for и while чем всякие std::foreach) так же и в вебинге сделали, заменили нормальную связку php js и html всякими докерами ангулярами ларавелами и тд. короче это не облегчение коду а наоборот гемор каждый год придумывают.
 
money++
Разработчик
Статус
Оффлайн
Регистрация
14 Июн 2018
Сообщения
638
Реакции[?]
339
Поинты[?]
22K
1. Используйте эффективные структуры данных.
Пример: При работе с большими объемами данных, выбирайте структуры данных, оптимальные с точки зрения доступа и изменения данных.
C++:
std::map<int, std::string> myMap; // для быстрого поиска по ключу
Если тебе нужен только поиск по ключу - используй std::unordered_map, в std::map поиск/вставка/удаление работают за O(logN), в unordered - O(1)... std::map имеет смысл если тебе нужны lower/upper bound и умение обходить элементы в посорченом порядке.
 
Начинающий
Статус
Оффлайн
Регистрация
2 Сен 2019
Сообщения
31
Реакции[?]
12
Поинты[?]
3K
Лучше бы расписал простым языком про то, почему именно это является более лучшем решением (кроме рефов). К тому же, если зелёному сказать "использую многопоток", он без разбора будет её пихать везде без знания подводных камней, а потом получить ub из-за незнания механизмов синхронизации.
 
Nike.lua
Олдфаг
Статус
Оффлайн
Регистрация
13 Окт 2020
Сообщения
2,747
Реакции[?]
1,465
Поинты[?]
2K
Пример: Используйте префиксные операции вместо постфиксных, если это возможно, для уменьшения затрат.
а разница то какая, компилятор превратит это все в одну инструкцию. Дальше читать не захотелось
 
Keine panik!
Эксперт
Статус
Оффлайн
Регистрация
29 Апр 2020
Сообщения
812
Реакции[?]
417
Поинты[?]
49K
Ты описываешь способы, но не описываешь причины и ньюансы
Чтобы понимать причины, нужно знать устройство, а кто его знает, эти советы являются очевидными
1. Каждый контейнер реализован по своему, поэтому имеет эффективность в различных кейсах
Например вектор это про быстрое добавление элементов в конец и быстрый произвольный доступ, потому что память выделяется единым блоком подо все элементы и запасом, но у него медленное добавление в начало, потому что все элементы нужно передвигать, так же линейный поиск потому что все элементы нужно перебрать, так же итераторы могут сломаться при изменении элементов, т.к. это просто индекс в массиве
set/map выделяет узлы на каждый элемент, это плюс т.к. итераторы остаются валидными после изменений элементов, под капотом используется красно-черное дерево, которое на большинстве юзеркейсов будет быстрее авл дерева
unordered_set/map вообще использует хэшкарту, из-за этого быстрый поиск по ключу
В общем все типы контейнеров нужно изучать, а не просто зазубривать какой когда юзать
2. Это будет работать только в случае сложных итераторов, т.к. при префиксной форме у тебя создается копия итератора (которая возвращается в качестве результата), а затем инкрементируется сам итератор
Т.е. условно если у тебя интегральный тип, то оптимизатор легко сожрет это
3. Тут не доебаться, объяснено :)
4. Многопоточность новичку может принести больше вреда, чем пользы, т.к. многопоток это глубокое понимание того, как код может выполняться одновременно, сразу требуется знание примитивов синхронизации, и это ни чуть не проще чем контейнеры, т.к. неправильно синхронизировав можно получить в лучшем случае убитый перф, а в худшем гайзен краши
 
Администратор
Администратор
Статус
Оффлайн
Регистрация
17 Сен 2016
Сообщения
2,144
Реакции[?]
1,746
Поинты[?]
172K
1. Используйте эффективные структуры данных.
Пример: При работе с большими объемами данных, выбирайте структуры данных, оптимальные с точки зрения доступа и изменения данных.
C++:
#include <vector>
#include <map>

int main() {
    // Использование эффективных контейнеров STL
    std::vector<int> vec; // для последовательного доступа
    std::map<int, std::string> myMap; // для быстрого поиска по ключу
    return 0;
}
2. Оптимизация циклов.
Пример: Используйте префиксные операции вместо постфиксных, если это возможно, для уменьшения затрат.


C++:
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // Плохо: использует постфиксный инкремент
    for (int i = 0; i < vec.size(); i++) {
        // делать что-то
    }

    // Хорошо: использует префиксный инкремент
    for (int i = 0; i < vec.size(); ++i) {
        // делать что-то
    }

    return 0;
}

3. Используйте ссылки вместо копирования.
Пример: Передавайте объекты по ссылке, чтобы избежать лишних копирований.


C++:
#include <vector>
#include <iostream>

// Плохо: передача вектора по значению
void processVector(std::vector<int> data) {
    // делать что-то
}

// Хорошо: передача вектора по ссылке
void processVectorEfficiently(const std::vector<int>& data) {
    // делать что-то
}

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    processVector(vec); // Плохо
    processVectorEfficiently(vec); // Хорошо
    return 0;
}

4. Используйте многопоточность.
Пример: Разбейте задачи на потоки для более эффективного использования многопроцессорных систем.


C++:
#include <iostream>
#include <thread>
#include <vector>

// Функция, выполняемая в потоке
void processChunk(const std::vector<int>& chunk) {
    // обработка куска данных
}

int main() {
    std::vector<int> data = { /* большой массив данных */ };
    const int numThreads = 4;

    // Разбиваем данные на куски и обрабатываем параллельно
    std::vector<std::thread> threads;
    size_t chunkSize = data.size() / numThreads;
    for (int i = 0; i < numThreads; ++i) {
        auto start = data.begin() + i * chunkSize;
        auto end = (i == numThreads - 1) ? data.end() : start + chunkSize;
        threads.emplace_back(processChunk, std::vector<int>(start, end));
    }

    // Дожидаемся завершения всех потоков
    for (auto& thread : threads) {
        thread.join();
    }

    return 0;
}
задавайте вопросы, отвечу.
так-же можете предложить свои улучшения, добавлю.
с наступающим всех)​
Зачем на форуме статья, сгенерированная чатгпт?
 
Легенда форума
Статус
Оффлайн
Регистрация
10 Дек 2018
Сообщения
4,371
Реакции[?]
2,278
Поинты[?]
182K
Сверху Снизу