存储大量数值模拟输出的最佳方法 我正在开发C++中的应用程序,在那里我将运行数值模拟并以某种方式存储仿真结果。每个模拟点将与许多字段(即浮点数)相关联,每个字段必须存储许多小数

存储大量数值模拟输出的最佳方法 我正在开发C++中的应用程序,在那里我将运行数值模拟并以某种方式存储仿真结果。每个模拟点将与许多字段(即浮点数)相关联,每个字段必须存储许多小数,c++,linux,database,C++,Linux,Database,到目前为止,我正在将数据写入一个简单的文本文件(每个模拟点一行)。原则上,这是可行的,但由于字段数量多,每个字段都有大量的小数,因此文件中的列数非常大。有时我希望手动检查该文件,大量的列就会成为一个问题 有没有比简单地将数据写入文本文件更好的方法来存储数据?我应该把输出分成几个文件吗?我是否应该考虑将输出写入某种类型的数据库中,在那里我可以以完全精确的方式存储字段并检查某种GUI应用程序的输出?欢迎提出其他建议!请注意,该应用程序将在Linux上运行。这有点正交,但根据对您的问题的任何答案的上下

到目前为止,我正在将数据写入一个简单的文本文件(每个模拟点一行)。原则上,这是可行的,但由于字段数量多,每个字段都有大量的小数,因此文件中的列数非常大。有时我希望手动检查该文件,大量的列就会成为一个问题

有没有比简单地将数据写入文本文件更好的方法来存储数据?我应该把输出分成几个文件吗?我是否应该考虑将输出写入某种类型的数据库中,在那里我可以以完全精确的方式存储字段并检查某种GUI应用程序的输出?欢迎提出其他建议!请注意,该应用程序将在Linux上运行。

这有点正交,但根据对您的问题的任何答案的上下文依赖程度,我认为这在这里是合适的

考虑到您的犹豫,我强烈建议您添加一层间接寻址,这样您就可以轻松地支持各种格式和/或类似于交换专用文件输出线程之类的内容

按照这些思路应该做些事情:

struct-StepData{
//...
};
类数据链路{
公众:
虚拟~DataSink(){}
虚拟无效推送(const StepData&data)=0;
};
//将数据转储为二进制。
类ToBinaryFileSink final:公共数据链路{
静态断言(std::是可复制的,“步骤数据不能被memcpyed”);
std::ofstream\u文件;
公众:
ToBinaryFileSink(常量std::字符串和文件名)
:_文件(文件名,std::ios::二进制){
//大概写一些有趣的标题吧。
}
~ToBinaryFileSink(){
//大概写些有趣的页脚吧。
}
无效推送(常量步骤数据和数据)覆盖{
_file.write(&data,sizeof(data));
}
}
请注意:

  • final
    关键字。在这里,当直接使用sink子类或编译器使用devirtualization时,消除虚拟调用开销非常有用
  • DataSink
    旨在鼓励在生成结果时流式传输,而不是在模拟结束时收集所有数据并将其转储,无论最终的文件格式如何,这几乎肯定是您想要的
  • 如果您想变得更有趣,还可以在
    StepData
    类型上为
    DataSink
    设置模板,以及在sink类型上为模拟运行设置模板

如果都是固定大小的列和列数,您可以只编写一个二进制文件。a)压缩二进制文件。B) 压缩二进制+gzip。什么是“最佳”方式或征求建议完全是基于意见的。有时纯文本是最方便的。如果文件太大,您可以将其拆分为较小的文件。如果您决定将文件设置为二进制文件而不是文本文件,则您可能需要a来检查该文件。某些文本编辑器还支持以二进制模式查看文件。在某种GUI应用程序中检查输出?--该GUI应用程序可以是一个电子表格应用程序,您可以在其中隐藏和显示列。谢谢您的回答!我认为这是一种很好的组织方式。最后,我可能会将数据写入纯文本文件(便于检查,例如在电子表格程序中)和二进制格式(便于导入特定的模拟点并以全精度存储)。如果您有一对序列化器/反序列化器,因为您需要使用该数据,您总是可以编写一个快速命令行工具来转储二进制数据的文本版本。这不仅在调试时非常方便,而且在使用应用程序并尝试将其集成到其他工作流时也非常方便。支持@tadman的建议。在模拟应用程序本身中尽可能少地执行操作(毕竟,您希望它尽可能快地运行)。输出一次,然后根据需要在事实发生后进行转换通常是可取的。