До или после добавления в наборы в C ++ - PullRequest
2 голосов
/ 18 сентября 2011

С учетом

my_type m;
std::vector<my_type> v;

Что работает быстрее?

m.generate_data_inside_self();
v.push_back(m);

Или

v.push_back(m);
v[0].generate_data_inside_self();

Если бы вектор содержал указатели на my_types, тогда оба выглядели бы примерно одинаково.

Однако при копировании всего объекта my_type, как в этом примере, я думаю, что 2-й будет быстрее, так как копировать меньше, поскольку дополнительные данные появляются только после того, как "m" находится внутри "v".

редактирование:

В примере моей программы my_type выглядит примерно так.

my_type
{
    private:
        std::vector<unsigned short> data; //empty after construction

    public:
        //no destructors, assignment operators
        //copy constructors etc... explicitly (are) defined
        generate_data_inside_self() //populates data
        {
            //contains for example a loop that populates
            //"data" with some (lets say 50) values
        }
}

Ответы [ 6 ]

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

Добавьте его, когда сложность конструктора / оператора копирования == меньше.Если вы генерируете данные, что, скорее всего, увеличивает сложность, вставьте перед генерацией.

Если у вас много векторных копий и вас беспокоит производительность, я предлагаю иметь vector указателей и new(и, конечно, однажды delete) объекты и положить их в vector.Таким образом, стоимость вставки в vector не зависит от сложности объекта.

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

Если вы беспокоитесь о производительности здесь, не используйте std::vector<my_type>. Vector копирует все элементы при каждом перераспределении памяти и может копировать элементы при удалении элементов из вектора. Используйте boost::ptr_vector или std::vector<boost::shared_ptr>, это повышает производительность в обоих случаях: добавление элементов в вектор и перераспределение / стирание.

EDIT:

Я пересмотрел свой ответ:

Второй подход имеет лучшую производительность, потому что позволяет избежать копирования заполненного my_type экземпляра (в отличие от созданного по умолчанию с пустым std::vector членом) при добавлении в вектор. Но он менее читабелен и менее канонический . Я бы рекомендовал использовать первый подход по умолчанию один и только после профилирования, чтобы выборочно использовать второй подход или, как я ранее предлагал, использовать boost::ptr_vector или std::vector<boost::shared_ptr>

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

Извините, но это слишком сильно зависит от вашего типа. Если он содержит указатели на какой-то большой внешний блок данных, его копирование может занять совсем немного времени, но вы можете обнаружить, что копирование после генерации данных происходит очень медленно. Только вы знаете, и, если вам небезразлична производительность, единственный способ выяснить это - нажать ее в цикле for и рассчитать время.

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

Это зависит от того, как именно определен тип, и от того, что делает вызываемая вами функция.

В обоих случаях объект m копируется в вектор после построения.

Таким образом, ответ зависит от того, делает ли generate_data_inside_self копию дороже или нет.И это зависит от того, как определяется оператор присваивания.(И существует ли в C ++ 11 оператор присваивания перемещения и разрешено ли его вызывать.)

Но, как всегда в вопросах производительности, единственный ответ, который имеет значение, это тот, который вы получаете, когдаВы запускаете код.Если вы хотите узнать, что быстрее, рассчитайте время и убедитесь сами.

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

Размер m фиксирован в обоих примерах. Любые данные, которые вы генерируете в generate_data_inside_self(), либо просто заполняют дыры, либо выделяют пространство, которое vector не заботит (то есть в куче).

И, что более важно, содержимое этих данных непрозрачно с точки зрения vector, поэтому оно не влияет на производительность, если случается, что это все нули или случайный набор значений; весь блок размером sizeof(m) копируется в любом случае.

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

Если вы не предоставите нам больше данных, я думаю, что зависит от того, что содержит ваш класс и какие данные он должен генерировать. Трудно сказать, что будет быстрее, поскольку могут быть вещи, которые мы не можем определить по вашему вопросу.

...