如何知道对从文件解析的数据使用 std::array 还是 std::vector,以及如何提高分配性能?

How do I know whether to use a std::array or std::vector for data parsed from a file, and how can I improve allocation performance?

提问人:zogac 提问时间:3/25/2023 最后编辑:starballzogac 更新时间:3/25/2023 访问量:61

问:

我有一个输入文件,它有逐行的 3D 矢量数据。我想读取此矢量数据并将其存储在程序中。我以为我有两个选择:

我可以计算行数,并且可以创建一个固定数组 或 我可以将我的“矢量数据”插入到对象中std::vectorpush_back

我的问题是哪一个是完成该任务的最快方法?

如果有其他方法可以做到这一点,请解释一下。

C++ 数组解析 stdvector stdarray

评论

1赞 Alex 3/25/2023
对于数组,您都需要知道编译时的行数,因此您建议的唯一选择是(您也可以进行基准测试和,但我会说从向量开始)。编辑:如果您的意思是手动计算行数并使用 ,那么这确实有效。我会说它可能会更快一些,但你应该对它进行基准测试以了解它。std::arraystd::vectorstd::liststd::forward_liststd::array
0赞 Paul Sanders 3/25/2023
文件有多大?首先担心正确性,其次才担心速度。

答:

2赞 starball 3/25/2023 #1

这与其说是速度问题,不如说是输入的性质问题,因为这确实是合适的集合类型所依赖的。

如果输入文件具有固定的行数(该数字在编译时是已知的),并且所有此类输入文件都具有相同的行数,则可以使用支持编译时已知大小的容器(例如 ),并在文件提供意外行数时引发异常或使用其他错误处理机制。std::array

如果此类型的所有此类输入文件的行数都不相同,则必须使用在运行时支持可变大小(非编译时已知大小)的容器,例如 .在这种情况下,如果要在增加容器的基础缓冲区容量时避免不必要的重新分配性能成本,则可以考虑更改输入文件的格式,使其从描述数据行数开始(现在,您基本上是为输入文件架构提供标头部分来描述以下数据的性质)。然后,在读取文件时,可以读取标头,并使用其中包含的值来调用 reserve。当然,您还需要调整程序中写入这些文件的部分,以使标头信息与数据保持同步。如果你使用这样的头文件,并且不相信输入文件会被正确写入(这实际上是一个合理的想法),你也不应该假设数据线的数量与头中报告的数字相匹配,并抛出异常或在适当的时候使用你的项目错误信号方法。std::vector

由程序控制的分配性能之外的性能实际上并不在您的控制范围内 - 例如,磁盘性能在很大程度上取决于磁盘类型、文件系统类型以及操作系统从文件中读取的行为。我相信您仍然可以做的是调整标准输入流底层缓冲的缓冲区大小(参见 std::basic_ios<CharT,Traits>::rdbuf),但这是否可以导致改进的性质可能最终取决于上述因素。但是,请查看 std::ios_base::sync_with_stdio,看看它是否适合您的程序。