我有一个应用程序可以执行大量的文件I / O(在其生命周期内~3-6小时,大约0.5-0.75TB,主要是文件输出).
目前我的应用程序sprintf()将所有内容都放入char字符串中,并在一行write()s的末尾添加到file_descriptor中.我的字符串长度为1024个字符,但可以在64到1024之间变化.无论如何.
问题是:在执行write()之前,将更大的字符串(例如,1MB?)和sprintf()所有内容都更有意义吗?或者完全跳过sprintf()并直接将write()直接写入文件更有意义,假设缓冲由write()处理?
我想到的东西,但不确定它是否真的可以在性能方面取得任何成就:
如果我有一个结构,我存储字符串的各个部分,数字和字符串,并对结构进行mem_copy,该怎么办?我猜是类似于二进制写?
我正在尝试实现“缓冲”方法或任何可以最大化性能的方法.
后者是我需要使用该文件进行进一步处理.
有什么建议?
编辑
我用printf()做了一些简单的性能比较; redir和sprintf();写();我只是将〜20GB复制到一个文件中.
char string[1024]; for(i=0;i<(1<<20)*20;i++) printf("%s",string); ~/tmp/tests$time ./printf.out > testing real 2m22.101s user 0m28.214s sys 0m29.294s
而不是:
char string14[256]; ...etc for(i=0;1<<(1<<20)*20;i++){ sprintf(dst_string,"%s%s",dst_string, string14); sprintf(dst_string,"%s%s",dst_string, string24); sprintf(dst_string,"%s%s",dst_string, string34); sprintf(dst_string,"%s%s",dst_string, string44); write(fd, dst_string, 1024); } ~/tmp/tests$time ./write.out real 1m48.206s user 0m58.544s sys 0m41.079s
多个sprintf()的原因是模拟copy-gt;缓冲区然后写入缓冲区.
时间(实际上无论如何)并不像某些评论所暗示的那样微不足道.虽然这是一个简单的例子,也许在计算方案IO中可能不会.
我在printf示例中有点困惑的事情,那个额外的时间去了哪里?用户系统不加起来真的,难道他们至少不应该在球场?因为整个1:30m缺失了.
该测试是否显示任何结论? sprintf write>只需打印redir?
无论如何,谢谢大家的评论.
当我在我的机器上进行一些测试时,我从不那么现代的硬件中获得了大约60MB / s的速度.这是3.6GB /分钟或216GB /小时(所以3小时产生大约640GB).我希望你的应用程序花费的时间主要是“等待磁盘”,在这种情况下,你使用的IO方法绝对没有区别.但是就像所有的表现问题一样,这不是你可以通过互联网询问,或者在书中或其他任何地方查找的答案.它必须在您关注的系统上进行测量.为一些配置得很好的RAID改变我那些笨拙的旧硬盘,你会得到更好的性能[如果它是正确的raid系统 – 有些比单个磁盘慢,因为它的目的不是为了加快访问速度,而是为了确保可靠性].
你也可以做一些比较:
1.将软件的输出重定向到/ dev / null – 检查现在运行代码所需的时间.如果它比你写文件时快10到100倍,那么你就知道你现在写的方式或其他方法根本没有任何区别.
2.用dd if = / dev / zero of = yourfile bs = 4k count = largenumber(largenumber * 4KB =典型文件大小)创建类似大小的文件 – 如果你的应用程序正在写几个文件,那么写一个写几个不同文件的脚本这样的文件).如果这比您的应用程序快得多,那么通过改变从应用程序输出的方式可以获得一些东西.
如果上述两个方面中的任何一个都表明存在增益潜力,那么编写一些产生大量输出的基准测试,就像您希望应用程序工作一样,看看有什么区别.一定要回到这里问问题.但我的猜测是,无论你对输出机制做什么,你的应用程序都不会运行得更快或更慢,因为它完全取决于“磁盘写得多快”.