На сколько эффективно выносить объявление переменных из циклов?

Был слушок, что объявление переменных в цикле плохая идея. Я хочу узнать так ли это и на сколько. Условно. У меня есть 3 * 10^9 запросов, на каждом запросе я вношу в некий массив id и строку с чем-то. Вот это "плохой код".

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main() {
    //...
    vector <int> arrayId;
    vector <string>   arrayStr;
    for (int i = 0; i < 3 * 1000 * 1000 * 1000; i++) {
        string str;
        int id;
        cin >> id >> str;
        arrayStr.push_back(str);
        arrayId.push_back(id);
    }
    //...
    return 0;
}

На сколько будет эффективнее(по памяти и скорости) вынести инициализацию переменных из цикла ?


Ответы (1 шт):

Автор решения: AlexGlebe

Внутри цикла происходит конструирование локальной переменной string str; и дальше её деструктор несколько раз.

for (long int i = 0; i < 3L * 1000L * 1000L * 1000L; i++) {
    string str;
    // конструктор str
    int id;
    cin >> id >> str;
    arrayStr.push_back(str);
    arrayId.push_back(id);
   // деструктор str
}

Вынос переменной за пределы цикла конечно ускорит программу. Но самую большую пользу принесёт быстрый перенос строки в arrayStr без копирования с помощью переноса std::move. После этого память для введённой строки может быть перенесена в arrayStr путём обмена указателями (быстро).

string str;
for (long int i = 0; i < 3L * 1000L * 1000L * 1000L; i++) {
    int id;
    cin >> id >> str;
    arrayStr.push_back(std::move(str));
    // здесь память введённой строки уже у последнего элемента arrayStr
    // теперь str может быть равна пустой строке
    arrayId.push_back(id);
}

(int)3'000'000'000 == -1294967296

→ Ссылка