嵌套向量的缺点是什么?
What are the Disadvantages of Nested Vectors?
我对C++还很陌生,还有很多东西要学,但我最近变得非常依恋的是使用嵌套(多维(向量。 所以我通常可能会得到这样的东西:
std::vector<std::vector<std::string> > table;
然后我可以轻松访问这样的元素:
std::string data = table[3][5];
然而,最近我的印象是(就性能而言(最好有一个一维向量,然后只使用"索引算法"来相应地访问元素。 我认为这种性能影响对于更大或更高维的向量是显着的,但老实说,我不知道,到目前为止也找不到太多关于它的信息。
虽然从直觉上讲,单个向量比高维向量具有更好的性能是有道理的,但老实说,我不明白实际原因。 此外,如果我只使用一维向量,我将失去访问多维向量元素的直观语法。 所以这是我的问题:
为什么多维向量效率低下? 如果我只使用一维向量(以更高维度表示数据(,那么访问其元素的最佳、最直观的方法是什么?
这取决于确切的条件。我将讨论这种情况,当嵌套版本是真正的 2D 表时(即所有行的长度相等(。
一维矢量通常在每种使用模式上都会更快。或者,至少,它不会比嵌套版本慢。
嵌套版本可以认为更糟,因为:
- 它需要分配行数时间,而不是一个。
- 访问元素需要额外的间接寻址,因此速度较慢(额外的间接寻址通常比一维情况下所需的乘法慢( 如果按
- 顺序处理数据,那么如果 2D 数据分散在内存周围,则速度可能会慢得多。这是因为可能存在大量缓存未命中,具体取决于内存分配器返回不同行的内存区域的方式。
因此,如果您追求性能,我建议您为 1D 向量创建一个 2D 包装器类。这样,您可以获得与嵌套版本一样简单的 API,并且您也将获得最佳性能。甚至,如果出于某种原因,您决定改用嵌套版本,您可以更改此包装器类的内部实现。
访问 1D 元素的最直观方法是y*width+x
.但是,如果您知道自己的访问模式,则可以选择其他访问模式。例如,在绘画程序中,基于图块的索引可能更适合存储和操作图像。在这里,可以像这样索引数据:
int tileMask = (1<<tileSizeL)-1; // tileSizeL is log of tileSize
int tileX = x>>tileSizeL;
int tileY = y>>tileSizeL;
int tileIndex = tileY*numberOfTilesInARow + tileX;
int index = (tileIndex<<(tileSizeL*2)) + ((y&tileMask)<<tileSizeL) + (x&tileMask);
此方法在内存中具有更好的空间局部性(彼此靠近的像素往往具有接近的内存地址(。索引计算比简单的y*width+x
慢,但这种方法的缓存未命中率要少得多,所以最终可能会更快。
- 使用rdtsc进行基准测试的缺点是什么
- 将字段(在类中)定义为引用的缺点是什么?
- 嵌套向量的缺点是什么?
- 模板而不是接口的缺点是什么?(C++)
- 在C 项目中剩下未使用的类的缺点是什么?
- 在64位系统上创建一个非常大的数组的缺点是什么
- C++协方差返回类型的缺点是什么
- 在将GITHUB库包含在您的项目中之前,汇编GitHub库的优点 /缺点是什么?
- 单源项目结构的缺点是什么?
- 仅使用UDP托管小型服务器应用程序的缺点是什么
- 如果我使用数组而不是矢量,有什么缺点吗?
- 抛弃灾难的例外 - 缺点是什么
- 使用继承来减少重复代码的缺点是什么
- 使用'?'而不是L'?wchar_t'有什么缺点吗?
- 以不同方式实现可变参数构造函数的模板类:每个版本的优点和缺点是什么
- 如果使单一实例构造函数受到保护,缺点是什么 - 继承 - C++11.
- 为C++提供标准GUI库的缺点是什么
- 如何访问类变量?公共方法/getters与继承.优点和缺点是什么
- 对所有异常使用一个基类的缺点是什么?
- 使用AVL树的缺点是什么?