STL векторы с неинициализированным хранилищем? - PullRequest
40 голосов
/ 19 сентября 2008

Я пишу внутренний цикл, который должен поместить struct s в непрерывное хранилище. Я не знаю, сколько из этих struct будет раньше времени. Моя проблема в том, что STL vector инициализирует его значения 0, поэтому независимо от того, что я делаю, я несу расходы на инициализацию плюс стоимость установки элементов struct в их значения.

Есть ли какой-нибудь способ предотвратить инициализацию или существует STL-подобный контейнер с непрерывным изменяемым размером хранилища и неинициализированными элементами?

(я уверен, что эту часть кода нужно оптимизировать, и я уверен, что инициализация требует значительных затрат.)

Также, смотрите мои комментарии ниже для разъяснения о том, когда происходит инициализация.

НЕКОТОРЫЙ КОД:

void GetsCalledALot(int* data1, int* data2, int count) {
    int mvSize = memberVector.size()
    memberVector.resize(mvSize + count); // causes 0-initialization

    for (int i = 0; i < count; ++i) {
        memberVector[mvSize + i].d1 = data1[i];
        memberVector[mvSize + i].d2 = data2[i];
    }
}

Ответы [ 14 ]

1 голос
/ 19 сентября 2008

Используйте метод std :: vector :: reserve (). Он не изменит размер вектора, но выделит пространство.

0 голосов
/ 19 сентября 2008

Я бы сделал что-то вроде:

void GetsCalledALot(int* data1, int* data2, int count)
{
  const size_t mvSize = memberVector.size();
  memberVector.reserve(mvSize + count);

  for (int i = 0; i < count; ++i) {
    memberVector.push_back(MyType(data1[i], data2[i]));
  }
}

Вам необходимо определить ctor для типа, который хранится в memberVector, но это небольшая стоимость, поскольку она даст вам лучшее из обоих миров; не выполняется ненужная инициализация, и во время цикла перераспределение не произойдет.

0 голосов
/ 19 сентября 2008

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

int *memberArray;
int arrayCount;
void GetsCalledALot(int* data1, int* data2, int count) {
    memberArray = realloc(memberArray, sizeof(int) * (arrayCount + count);
    for (int i = 0; i < count; ++i) {
        memberArray[arrayCount + i].d1 = data1[i];
        memberArray[arrayCount + i].d2 = data2[i];
    }
    arrayCount += count;
}
0 голосов
/ 19 сентября 2008

Нужно ли, чтобы сами структуры находились в смежной памяти, или вы можете избавиться от наличия вектора структуры *?

Векторы копируют все, что вы добавляете к ним, поэтому использование векторов указателей, а не объектов, является одним из способов повышения производительности.

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