C++ 选择性能最好的容器(阵列)
这是我关于容器的一个大问题,特别是数组 我正在写一个物理代码,主要操作一大组(>1000000)的“粒子”(每个粒子有6个C++ 选择性能最好的容器(阵列),c++,C++,这是我关于容器的一个大问题,特别是数组 我正在写一个物理代码,主要操作一大组(>1000000)的“粒子”(每个粒子有6个double坐标)。我正在寻找实现一个类的最佳方法(就性能而言),该类将包含这些数据的容器,并为这些数据提供操作原语(例如实例化、operator[]等) 如何使用此集合有一些限制: 它的大小是从配置文件读取的,在执行期间不会更改 可以将其视为一个由N(例如1000 000)行和6列(每个列存储一维坐标)组成的大二维数组 数组在一个大循环中操作,访问每个“粒子/线”,并使用
double
坐标)。我正在寻找实现一个类的最佳方法(就性能而言),该类将包含这些数据的容器,并为这些数据提供操作原语(例如实例化、operator[]
等)
如何使用此集合有一些限制:
- 它的大小是从配置文件读取的,在执行期间不会更改
- 可以将其视为一个由N(例如1000 000)行和6列(每个列存储一维坐标)组成的大二维数组
- 数组在一个大循环中操作,访问每个“粒子/线”,并使用其坐标进行计算,然后将结果存储回该粒子,依此类推每个粒子,依此类推大循环的每次迭代
- 在执行过程中不会添加或删除新元素
[]
逐个访问每个元素来完成的,因此我认为应该使用普通的动态数组
我已经探索了一些东西,我想听听你对能给我最好表现的那个的看法
据我所知,使用动态分配的数组而不是std::vector
,没有任何优势,因此排除了double**array2d=new…、new循环等情况
那么使用std::vector
是一个好主意吗
如果我使用一个std::vector
,我应该创建一个像std::vector my_array
那样可以像my_array[I][j]
那样索引的二维数组,还是一个坏主意,最好使用std::vector other_array
并使用other_array[6*I+j]
也许这可以提供更好的性能,特别是当列的数量是固定的并且从一开始就知道时
如果您认为这是最好的选择,那么是否可以将此向量包装成一种可以使用定义为other_array[i,j]//与other_array[6*i+j]
的索引运算符访问的方式,而无需开销(如每次访问时的函数调用)
另一个选项,我目前使用的是Blitz,特别是Blitz::Array
:
typedef blitz::Array<double,TWO_DIMENSIONS> store_t;
store_t my_store;
typedef闪电战::数组存储\u t;
存储我的存储;
我的元素是这样访问的:myu存储(行、列)代码>
我认为在我的例子中使用Blitz没有什么好处,因为我一个接一个地访问每个元素,如果我直接在数组上使用操作(比如矩阵乘法),Blitz会很有趣,而我不是
你认为闪电战可以吗,还是对我没用
到目前为止,这些都是我考虑过的可能性,但也许是最好的一个,我还是另一个,所以请不要犹豫,给我提出其他建议
非常感谢你在这个问题上的帮助
编辑:
从下面非常有趣的答案和评论来看,一个好的解决方案似乎是:
- 使用结构<代码>粒子
(包含6个双精度)或6个双精度的静态数组(避免使用二维动态数组)
使用此粒子
结构或数组的向量
或deque
。然后最好使用迭代器遍历它们,这将允许以后从一个迭代器更改到另一个迭代器
此外,我还可以使用一个Blitz::TinyVector
而不是一个结构。首先,您不想将一个给定粒子的坐标分散到所有地方,因此我将首先编写一个简单的结构
:
struct Particle { /* coords */ };
然后我们可以把这些粒子
做成一个简单的一维数组
我可能会使用一个deque
,因为这是默认的容器,但您可能希望尝试一个vector
,它只是1.000.000个粒子意味着大约几兆字节的单个块。它应该可以保持,但如果它增长,可能会使系统紧张,而deque
将分配几个块
警告:
正如Alexandre C所说,如果你走deque
之路,不要使用操作符[]
,而是更喜欢使用迭代风格。如果您确实需要随机访问,而且它对性能非常敏感,那么向量应该更快
那么使用std::vector
是一个好主意吗
通常,容器的首选应该是std::vector
。您可以使用std::vector::reserve()
或std::vector::resize()
来避免在填充向量时重新分配。通过测量可以发现是否有其他容器更好。只有通过测量。但首先要衡量容器涉及的任何内容(填充、访问元素)是否值得优化
如果我使用std::vector,我应该创建一个像std::vector
[…]这样的二维数组吗
不,IIUC,您访问的是每个粒子的数据,而不是每行的数据。如果是这样,为什么不使用std::vector
,其中particle
是一个包含六个值的结构?即使我理解错误,你也应该在一维容器周围写一个二维包装。然后以行或列的形式对齐数据—使用访问模式会更快
你认为闪电战可以吗,还是对我没用
我对blitz++及其使用领域没有实际知识。但是blitz++不是全部都是关于表达式模板来展开循环操作和优化临时操作吗
other_array[i][j]
other_array(i, j) // if other_array implements operator()(int, int),
// but std::vector<> et al don't.
other_array[i].identifier // identifier is a member variable
other_array[i].identifier() // member function getting value
other_array[i].identifier(double) // member function setting value
struct Particle
{
double x[6];
double& speed() { return x[3]; }
double speed() const { return x[3]; }
double& acceleration() { return x[5]; }
...
};