Наиболее эффективный способ хранения смешанной коллекции удвоений и INT

StackOverflow https://stackoverflow.com/questions/1577696

  •  21-09-2019
  •  | 
  •  

Вопрос

Мне нужно хранить сборник INT и удвоений (представляющий номинальные и реальные ценные данные) в C ++. Я мог бы, очевидно, хранить их все в std::vector<double> , но это чувствует себя немного неправильно и не получает бонусных баллов эстетики.

Я также мог бы приготовить что -то на основе полиморфизма, но мне также нужно, чтобы коллекция была действительно эффективной: как хранение, так и получение данных в коллекции должно быть как можно быстрее. Мне трудно судить, будет ли такое решение максимально эффективным.

Я также нашел Boost :: Вариант, что может помочь здесь.

Дополнительная информация: количество элементов в коллекции будет небольшим (<100) и известно при инициализации коллекции.

Суммирование: я, очевидно, мог бы решить это бесчисленными способами, но я не уверен, что было бы хорошим решением, когда (i) эффективность действительно важна, и (ii) я также хочу написать несколько хорошего кода. Что здесь лучше всего?

Изменить, дополнительная информация: Коллекция представляет собой «строку» в более крупном наборе данных, его элементы представляют значения определенных «столбцов». Свойства строк известны, поэтому известно, какие данные хранятся, в какой позиции. «Эффективность», о которой я говорю, является в первую очередь эффективность извлечения значения INT/двойного значения определенного столбца, хотя быстрый настройка значений также важен. У меня есть некоторые функции, которые работают на данных, которые должны получить их как можно быстрее. Пример:

typedef std::vector<double> Row;

void doubleFun(Row const &row)
{
    // Function knows there's always a double at index 0
    double value = row[0];
    ...
}

void integerFun(Row const &row)
{
    // Function knows there's always an integer at index 1
    int value = row[1];
    ...
}

После еще некоторых размышлений и чтения предложений до сих пор кажется, что просто хранение столбцов Int и двойных столбцов в двух отдельных векторах является твердым решением. Коллекция Row Тогда может просто определить двух разных участников для получения номинальных и реальных данных, которые могут использовать функции.

Просто хранить как vector<double> Я думаю, это тоже нормально, но это зависит от того, насколько быстро преобразование между двойным и int (что, вероятно, довольно впечатляет).

Извините за то, что сначала неясно, я надеюсь, что это яснее, и теперь я смогу получить еще несколько мыслей по этому поводу.

Это было полезно?

Решение

Заказ важный момент в вашем контейнере?

Если не так:

class MyContainer
{
    std::vector<double> doubles;
    std::vector<int>    ints;

    push(double value) { doubles.push_back(value); }
    push(int value)    { ints.push_back(value); }

   ....
};

Часть итератора (для просмотра всего контейнера) может быть немного сложнее ...

Другие советы

Почему бы не использовать непосредственно вектор двойного? Поскольку целые числа могут быть преобразованы в удвоение без потери точности ... это кажется мне самым простым и наиболее эффективным решением.

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

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

Я не уверен, что ваша цель состоит в том, чтобы избежать тяжелых расчетов с плавающей запятой. Если это так, то битсет может быть более эффективным. Если нет, а точная точность int не важна, то вы можете просто хранить их все вдвое.

#include <vector>
#include <bitset>

union di
{
    double d;
    int i;
};


int main(int argc, char* argv[])
{

    std::bitset<2> bitsetInts;

    std::vector<di> v;
    di e1;
    e1.d = 3.9;
    v.push_back(e1);

    di e2;
    e2.i = 3;
    bitsetInts.set(1);
    v.push_back(e2);

    return 0;
}

Я бы пошел на boost::variant Решение, оно идеально соответствует вашим потребностям.

Существует буста, который вы можете использовать, если знаете типы во время компиляции. Но если количество предметов невелико, эффективно тратить 100 байтов не должно быть проблемой.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top