繁体   English   中英

在C ++中优化IO

[英]Optimizing IO in C++

我在优化C ++程序以实现最快的运行时遇到了麻烦。

该代码的要求是输出2个长整数之差的绝对值,并通过文件将其馈送到程序中。 即:

./myprogram < unkownfilenamefullofdata

文件名未知,每行有2个数字,以空格分隔。 有未知数量的测试数据。 我创建了2个测试数据文件。 一种是极端情况,长达5轮。 至于另一个,我使用一个Java程序生成2,000,000个随机数,并将其输出到一个timedrun文件中-相当于18.MB的测试。

大量文件的运行时间为3.4秒。 我需要将其分解为1.1秒。

这是我的代码:

int main() {
long int a, b;
while (scanf("%li %li",&a,&b)>-1){
  if(b>=a)
    printf("%li/n",(b-a));
  else
    printf("%li/n",(a-b));
  } //endwhile
return 0;
}//end main

我在程序上运行了Valgrind,它表明在读取和写入部分中有很多阻碍。 如果我知道我只会收到一个数字,该如何将打印/扫描重写为最原始的C ++形式? 有没有一种方法可以将数字扫描为二进制数字,并通过逻辑运算处理数据以计算出差异? 我还被告知要考虑编写一个缓冲区,但是经过大约6个小时的网上搜索并尝试编写代码,我没有成功。

任何帮助将不胜感激。

您需要做的是将整个字符串加载到内存中,然后从那里提取数字,而不是重复进行I / O调用。 但是,您可能会发现,从硬盘驱动器加载18MB只是花费大量时间。

您可以在scanf上进行很大的改进,因为可以保证文件的格式。 由于您确切地知道格式是什么,因此您不需要进行太多的错误检查。 另外,printf会在新行上转换为适合您平台的换行符。

我使用了与本SPOJ论坛帖子中类似的代码(请参阅本页面后面的 nosy帖子),以在读取整数区域中获得相当大的加速。 您将需要对其进行修改以处理负数。 希望它也会为您提供一些有关如何编写更快的printf函数的想法,但我将从替换scanf开始,看看能为您带来多大的帮助。

正如您所建议的,问题在于读取所有这些数字并将其从文本转换为二进制。

最好的改进是从任何将二进制数生成的程序中写出数字。 这将大大减少必须从磁盘读取的数据量,并略微减少从文本转换为二进制文件所需的时间。

您说2,000,000个数字占用18MB =每个数字9个字节。 这包括空格和行标记的结尾,因此听起来很合理。

将数字存储为4字节整数将减少必须从磁盘读取的数据量的一半。 在节省格式转换的同时,可以预期性能会提高一倍。

由于您需要更多,因此需要更根本的东西。 您应该考虑将数据文件拆分为单独的文件,每个文件都放在自己的磁盘上,然后在自己的进程中处理每个文件。 如果您有4个核心并将处理分成4个独立的进程,并且可以连接4个高性能磁盘,那么您可能希望性能再提高一倍。 现在的瓶颈是操作系统磁盘管理,无法猜测操作系统将如何并行管理四个磁盘。

我假设这是您需要做的处理的大大简化的模型。 如果您的描述全部包含,那么真正的解决方案是在编写测​​试文件的程序中进行减法!

与在程序中打开文件并一次读取所有文件相比,将文件进行内存映射甚至更好。 对于程序可用的〜2GB地址空间,〜18MB没问题。

然后使用strtod读取数字并前进指针。

与输入重定向和scanf相比,我期望有5-10倍的加速。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM