存储双精度数和整数混合集合的最有效方法

发布于 2024-08-08 04:23:27 字数 1234 浏览 2 评论 0原文

我需要在 C++ 中存储整数和双精度数(表示名义数据和实值数据)的集合。显然,我可以将它们全部存储在 std::vector 中,但这感觉有点不对,并且没有获得美学加分。

我还可以根据多态性编写一些东西,但我还需要集合非常高效:存储和检索集合中的数据都应该尽可能快。我发现很难判断这样的解决方案是否能达到最大效率。

我还发现 boost::variant,这可能在这里提供帮助。

附加信息:集合中的项目数量很小(<100)并且在初始化集合时已知。

总结:我显然可以通过无数种方式解决这个问题,但我不确定当(i)效率非常重要并且(ii)我也想编写一些不错的代码时,什么是一个好的解决方案。我在这里最好的选择是什么?

编辑、附加信息:集合代表较大数据集中的“行”,其元素代表某些“列”的值。行的属性是已知的,因此知道什么类型的数据存储在哪个位置。我所说的“效率”主要是检索某个列的 int/double 值的效率,尽管快速设置值也很重要。我有一些对数据进行操作的函数,需要尽快检索数据。示例:

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 列和 double 列存储在两个单独的向量中是一个可靠的解决方案。然后,集合 Row 可以定义两个不同的成员来检索函数可以使用的名义数据和实际数据。

我想,仅存储为 vector 也可以,但这取决于 double 和 int 之间的转换速度(这可能相当令人印象深刻)。

抱歉一开始有点不清楚,我希望现在能更清楚了,我可以对此事有更多的想法。

I need to store a collection of ints and doubles (representing nominal and real valued data) in c++. I could obviously store them all in a std::vector<double> , but this feels a bit wrong and doesn't get the aesthetics bonus points.

I could also cook up something based on polymorphism, but I also need the collection to be really efficient: both storing and retrieving the data in the collection should be as fast as possible. I find it hard to judge whether such a solution would be maximally efficient.

I also found boost::variant, which might be of help here.

Additional info: the number of items in the collection will be small (<100) and known when initializing the collection.

Summarizing: I could obviously solve this in countless ways, but I am unsure what would be a good solution when (i) efficiency is really important and (ii) I also want to write somewhat nice code. What is my best bet here?

Edit, additional info: The collection represents a 'row' in a larger data set, its elements represent the values of certain 'columns'. The properties of the rows are known, so it is known what kind of data is stored at which position. The 'efficiency' I am talking about is primarily the efficiency of retrieving the int/double value of a certain column, although fast setting of values is important too. I have some functions that operate on the data that need to retrieve it as fast as possible. Example:

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];
    ...
}

After some more thought and reading the suggestions so far, it seems that just storing int columns and double columns in two separate vectors is a solid solution. The collection Row could then just define two different members for retrieving nominal and real data that the functions can use.

Just storing as a vector<double> is okay too I guess, but it depends on how fast the conversion between double and int is (which is probably pretty impressive).

Sorry for being a little unclear at first, I hope it's clearer and now and that I can get some more thoughts on the matter.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

帝王念 2024-08-15 04:23:28

订购是您容器中的一个重要点吗?

如果不是这样:

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

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

   ....
};

迭代器部分(浏览整个容器)可能会有点棘手......

Is ordering an important point in your container ?

If not so:

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

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

   ....
};

The iterator part (to browse the whole container) could be a little trickier...

夜声 2024-08-15 04:23:28

为什么不直接使用 double 向量?由于整数可以转换为双精度数而不会损失精度......在我看来,这是最简单、最有效的解决方案。

还有什么需要设置(我无法从你的问题中弄清楚)你如何区分正常值和真实值。在您可能选择的任何解决方案中,该问题仍然存在。

Why not using directly a vector of double? Since integers can be converted to doubles without loss of precision... it looks to me the simplest and most efficient solution.

What remains to be set (and I couldn't figure out from your question) how can you make the difference between normal and real values. The issue remains open in any solution you might choose.

伴随着你 2024-08-15 04:23:28

您可以使用联合类型并在向量中使用它。但在这种情况下,您必须有某种方法来知道向量的哪些元素应该被视为整数,哪些元素应该被视为双精度。要跟踪哪些是整数,哪些是双精度,您可以使用位集或类似的东西。

我不确定您的目标是否是避免繁重的浮点计算。如果是的话,那么位集可能会更有效。如果不是,并且精确的 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;
}

You could use a union type and use that in your vector. But in that case you'd have to have some way to know which elements of the vector should be treated as ints and which ones should be treated as doubles. To keep track of which ones are ints and which ones are doubles you could use a bitset or something like that.

I'm not sure if your goal is to avoid heavy floating point calculations. If it is then the bitset may be more efficient. If not, and exact int precision isn't important, then you might as well just store them all as doubles.

#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;
}
滥情哥ㄟ 2024-08-15 04:23:28

我会选择 boost::variant 解决方案,它完全满足您的需求。

I would go for the boost::variant solution, it perfectly fits your needs.

疏忽 2024-08-15 04:23:28

如果您在编译时知道类型,则可以使用 boost 元组。但如果项目数量很少,那么有效地浪费 100 个字节就不必担心了。

There is the boost tuple, which you can use if you know the types at compile time. But if the number of items is small, efficiently in wasting 100 bytes shouldn't be a concern.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文