2014-01-07 4 views
2

Есть ли какая-либо большая разница в распределении, освобождении и времени доступа между std::vector<> и new[], когда оба фиксированы и одинаковой длины?C++ std :: vector <> vs new [] performance

+5

Используйте профайлер. –

+3

Не должно быть. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' – Shahbaz

+1

Профилируйте его и посмотрите, но я ожидаю, что не будет никакой разницы. – Angew

ответ

9

В зависимости от типа и того, как вы его называете. std::vector<int> v(1000000); должен обнулить миллион ints, тогда как new int[1000000]; этого не делает, поэтому я бы ожидал разницы в скорости. Это одно место в std::vector, где вы можете оплатить нос за то, что вы не используете, если по какой-то причине вам не нужны начальные значения элементов.

Если вы сравните std::vector<int> v(1000000); с new int[1000000]();, то сомневаюсь, что вы увидите большую разницу. Существенный вопрос заключается в том, имеет ли один из них более оптимизированный цикл, задающий нули, чем другой. Если это так, то реализация другой пропустила трюк (или, более конкретно, оптимизатор).

+3

Но 'v (N)' и 'new T [N]' не сопоставимы. Вам нужно сохранить память и объекты отдельно. Таким образом, реальное сравнение с 'std :: vector v; v.reserve (N); '. Во всяком случае, «вектор» лучше, потому что он позволяет * сохранять четкое представление об объектах и ​​памяти. –

+0

@KerrekSB Я согласен с тобой, но можно утверждать и наоборот: 'T * t = new T [N]' позволяет вам сказать 't [n] = 42;', тогда как символ 'vector.reserve' не делает. – juanchopanza

+0

@juanchopanza: Нет, но 't [n]' предполагает, что у вас уже есть целый ряд объектов. Я имею в виду, да, у вас может быть какой-то странный «случайный доступ к неинициализированному хранилищу», но я считаю, что большинство реальных алгоритмов реального мира будут либо требовать разумного, существующего диапазона, либо иначе собирать коллекцию последовательно каким-то образом. Если вам действительно нужно, вы можете создать неинициализированный интерфейс с произвольным доступом. –

2

new это плохо, потому что это нарушает идиому единой ответственности, предположив два respon ­ Сиби ­ литий ­ связи: Распределение памяти и строительный объект. Сложность - враг здравомыслия, и вы сражаетесь с сложностью, разделяя проблемы и изолируя обязанности.

Стандартные библиотечные контейнеры позволяют делать именно это, и думают только о объектах. Кроме того, std::vector addionally позволяет вам думать о хранении, но отдельно, через интерфейсы reserve/capacity.

Так ради сохранения ясного ума о вашей логике программы, вы должны всегда предпочитаете контейнер, такие как std::vector:

std::vector<Foo> v; 

// make some storage available 
v.reserve(100); 

// work with objects - no allocation is required 
v.push_back(x); 
v.push_back(f(1, 2)); 
v.emplace_back(true, 'a', 10); 
+0

В каком смысле вы используете здесь термин * object *? (Я немного смущен.) – dyp

+0

@ DyP: Я думаю, в смысле 3.8? –

+0

«Стандартные библиотечные контейнеры позволяют вам делать именно это и думать только о * областях хранения *. Кроме того,' std :: vector' addionally позволяет вам думать о хранилище, но отдельно, используя «резервную// емкость» «интерфейсы». Просто поиск + замена не работает для меня :(- по крайней мере, это звучит запутанно – dyp

Смежные вопросы