что быстрее: воссоздать или очистить ()? - PullRequest
6 голосов
/ 08 сентября 2011

У меня есть вопрос о производительности std :: vector <> в C ++.Быстрее ли повторно использовать тот же вектор, вызывая его метод clear (), или быстрее воссоздать вектор?

Следующий пример не является реальным кодом, он только для того, чтобы прояснить вопрос:

//Example ONE: is this faster
std::vector<int> foo;
for(int i = 0; i < 100; ++i)
{
    foo.clear();
    for(int j = 0; j < 100; ++j)
    {
        foo.push_back(i+j);
    }
}

//Example TWO: or is that faster?
for(int i = 0; i < 100; ++i)
{
    std::vector<int> foo;
    for(int j = 0; j < 100; ++j)
    {
        foo.push_back(i+j);
    }
}

Ответы [ 7 ]

8 голосов
/ 08 сентября 2011

clear() не может по своему договору освободить память vector, вместо этого просто устанавливает внутренний флаг "size" на 0, так что метод будет быстрее.

2 голосов
/ 08 сентября 2011

Это зависит от реализации std::vector в используемой вами стандартной библиотеке C ++, но вполне вероятно, что первый случай будет быстрее, поскольку большинство реализаций фактически не освобождают выделенную память при вызове std::vector::clear.Таким образом, первый не выполняет повторное распределение, когда внутренний цикл был выполнен первый раз.

1 голос
/ 08 сентября 2011

Да. Нет. Первый быстрее, наверное. Это зависит. Единственный полезный ответ приходит от того, что вы профилируете свой собственный код в своей среде.

Попробуйте профилировать свой код, чтобы увидеть, что происходит. Компиляция вашей программы в ideone показывает, что для одного конкретного компилятора / os / machine / run ваш первый пример в 4 раза быстрее.

И эта программа показывает промежуточное решение, которое идет быстрее, чем # 2, медленнее, чем # 1, для этого конкретного компилятора / os / machine / run.

0 голосов
/ 08 сентября 2011

В этом конкретном случае повторное использование, вероятно, будет быстрее на большинстве машин. Вы храните примитивные данные, которые не нуждаются в уничтожении (или даже имеют деструктор). С другой стороны, если вектор содержит не POD-объекты, каждый элемент будет уничтожен вызовом clear. С третьей стороны, все накопленные данные в конечном итоге должны быть уничтожены.

0 голосов
/ 08 сентября 2011

Чтобы очистить вектор и уменьшить его емкость до минимума вашей реализации, Скотт Мейерс рекомендует трюк подкачки :

std::vector<int>().swap( foo );

Это также будет быстреечем перебирать вектор с помощью свернутого вручную цикла, чтобы восстановить его содержимое.

0 голосов
/ 08 сентября 2011

Вам придется запустить тесты для вашего компилятора. Методы clear() и allocate зависят от реализации.

0 голосов
/ 08 сентября 2011

Пример 2 имеет повторные выделения кучи для массива внутри std :: vector. Пример 1 быстрее, потому что он избегает многократного выделения памяти в куче, если только размер вектора не должен быть внутренне изменен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...