我目前将一组双精度从向量写入文本文件,如下所示:
std::ofstream fout;
fout.open("vector.txt");
for (l = 0; l < vector.size(); l++)
fout << std::setprecision(10) << vector.at(l) << std::endl;
fout.close();
但这需要很长时间才能完成。有没有更快或更有效的方法来做到这一点?我很想看到并学习它。
原文由 Diego Fernando Pava 发布,翻译遵循 CC BY-SA 4.0 许可协议
你的算法有两个部分:
将双数序列化为字符串或字符缓冲区。
将结果写入文件。
使用 sprintf 或 fmt 可以改进第一项(> 20%)。第二项可以通过将结果缓存到缓冲区或在将结果写入输出文件之前扩展输出文件流缓冲区大小来加快速度。您不应该使用 std::endl ,因为 它比使用 “\n” 慢得多。如果您仍然想让它更快,那么以二进制格式写入数据。下面是我的完整代码示例,其中包括我提出的解决方案和来自 Edgar Rokyan 的解决方案。我还在测试代码中包含了 Ben Voigt 和 Matthieu M 的建议。
下面是在我的 Linux 机器中使用 clang-3.9.1 和 -O3 标志获得的性能结果。我使用 Celero 收集所有性能结果。
我还对数字到字符串的转换算法进行了基准测试,以比较 std::stringstream、fmt::MemoryWriter 和 std::vector 的性能。
从上表我们可以看出:
Edgar Rokyan 解决方案比 stringstream 解决方案慢 10%。使用 fmt 库的解决方案是对 double、int 和 size_t 三种研究数据类型的最佳解决方案。 sprintf + std::vector 解决方案比双数据类型的 fmt 解决方案快 1%。但是,我不推荐将 sprintf 用于生产代码的解决方案,因为它们不优雅(仍然以 C 风格编写)并且不能开箱即用地处理不同的数据类型,例如 int 或 size_t。
基准测试结果还表明, fmt 是高级整数数据类型序列化,因为它比其他方法至少快 7 倍。
如果我们使用二进制格式,我们可以将该算法加速 10 倍。这种方法比写入格式化的文本文件要快得多,因为我们只从内存到输出的原始复制。如果您想拥有更灵活和便携的解决方案,请尝试 谷物 或 boost::serialization 或 protocol-buffer 。根据 这项性能研究,谷物似乎是最快的。