我正在运行主要受CPU速度限制的模拟代码。我对将数据输入/输出到用户界面并不感兴趣,只需将其保存到磁盘中就可以了。
什么是最快的解决方案,可以减少开销?输入输出流? printf的?我之前读过printf更快。这取决于我的代码,如果不进行分析就不可能得到答案吗?
这将在Windows中运行,输出数据需要采用文本格式,制表符/逗号分隔,格式/精度选项主要用于浮点值。
答案 0 :(得分:4)
我自己没有使用它们,但我听说内存映射文件为操作系统提供了最佳的优化机会。
修改:相关的question和Wikipedia article on memory mapped files - 都提到了效果优势。
答案 1 :(得分:4)
构造(大型)数据块,可以顺序写入并使用异步IO。
准确分析会很痛苦,请阅读有关该主题的一些文章:scholar.google.com。
答案 2 :(得分:3)
Scott Meyers的“更有效的C ++”第23点“考虑备用库”如果您更喜欢速度而不是安全性和可扩展性,建议使用stdio而不是iostream。值得一试。
答案 3 :(得分:3)
我的想法是你正在解决错误的问题。你为什么要写出大量的文本格式数据?如果是因为你希望它是人类可读的,那么编写一个快速的浏览器程序来动态读取二进制格式的数据 - 这样,模拟应用程序可以快速写出二进制数据,浏览器可以进行格式化的繁琐工作数据在需要时。如果是因为您正在使用某些stats包来读取和分析文本数据,那么请编写一个输入二进制数据的文件。
答案 4 :(得分:2)
最快的方法是在特定目标操作系统和硬件上运行的特定应用程序最快的方式。唯一明智的做法是尝试几种方法并计算时间。您可能不需要完整的配置文件,练习应该只需要几个小时。我会按顺序测试:
当我找到一个足够快的解决方案时,我会停下来。
答案 5 :(得分:2)
文本格式意味着它供人类消费。人类可以阅读的速度远远低于任何合理输出方法的速度。某处有矛盾。我怀疑“输出必须是文本格式”。
因此,我相信正确的是输出二进制,并提供单独的查看器将单个条目转换为可读文本。在观众中进行格式化只需要人们可以阅读的速度。
答案 6 :(得分:2)
将文件映射到内存(即使用Memory Mapped File),然后只需memcopy
数据,这是一种非常快速的读/写方式。
您可以使用多个线程/核心来写入数据,并且OS /内核将使用与虚拟内存相同的例程将页面同步到磁盘,可以期望将其优化为地狱和后端,或多或少。
首先,执行此操作时,内存中应该没有多少额外的副本/缓冲区。写入被中断捕获,并在写入页面后添加到磁盘队列中。
答案 7 :(得分:1)
以二进制模式打开文件,并将“未格式化”的数据写入光盘。
fstream myFile;
...
myFile.open ("mydata.bin", ios:: in | ios::out | ios::binary);
...
class Data {
int key;
double value;
char[10] desc;
};
Data x;
myFile.seekp (location1);
myFile.write ((char*)&x, sizeof (Data));
编辑:OP添加了“输出数据需要采用文本格式,无论是制表符还是以逗号分隔。”约束
如果您的应用程序受CPU限制,则输出格式是您不需要的开销。二进制数据的写入和读取速度比ascii快得多,在光盘上更小(例如,使用二进制文件写入的总字节数少于ascii),并且因为它更小,所以在网络中移动速度更快(包括安装的网络)文件系统)。所有指标都指向二进制作为良好的整体优化。
查看二进制数据可以在运行后使用一个简单的实用程序完成,该实用程序将数据以所需的任何格式转储到ascii。我鼓励将一些版本信息添加到生成的二进制数据中,以确保可以在转储实用程序中处理数据格式的更改。
从二进制转移到ascii,然后对printf与iostreams的相对性能进行争论可能不是你时间的最佳用途。
答案 8 :(得分:0)
最快的方法是基于完成的异步IO。
通过为OS提供一组要写入的数据(当调用返回时它实际上没有写入),操作系统可以对其进行重新排序以优化写入性能。
执行此操作的API是特定于操作系统的:在Linux上,其名为AIO;在Windows上称为Completion Ports。
答案 9 :(得分:0)
快速方法是使用双缓冲和多线程(至少两个)。
一个线程负责将数据写入硬盘驱动器。此任务检查缓冲区,如果不为空(或可能是其他规则),则开始写入硬盘驱动器。
另一个线程将格式化文本写入缓冲区。
硬盘驱动器的一个性能问题是加速并将磁头定位到正确位置所需的时间。为了避免这种情况发生,目标是不断写入硬盘驱动器,以便它不会停止。这很棘手,可能涉及程序范围之外的东西(例如同时运行的其他程序)。写入硬盘的数据块越大越好。
另一个刺是在硬盘上找到空插槽来放置数据。碎片硬盘驱动器比格式化或碎片整理的驱动器慢。
如果可移植性不是问题,您可以检查您的操作系统是否有一些API执行对硬盘驱动器的块写入。或者您可以降低速度并使用直接写入驱动器的API。
您可能还希望程序更改其优先级,以便它是最重要的任务之一。