我正在编写一个程序,其中性能非常重要,但并不关键。目前我正在阅读来自 FILE* 逐行,我用 fgets 获取每一行。使用一些性能工具后,我发现我的应用程序运行时有 20% 到 30% 的时间在内部 fgets.

有没有更快的方法来获取一行文本?我的应用程序是单线程的,无意使用多线程。输入可以来自标准输入或文件。提前致谢。

有帮助吗?

解决方案

你不说你是在哪个平台上,但如果它是类UNIX,那么你可能想尝试阅读()系统调用,它不缓冲该FGETS()等人的执行额外的层做。这可能会加快速度略有下降,而另一方面它很可能放慢改革的步伐 - 找出的唯一方法是尝试一下,看看

其他提示

  1. 使用 fgets_unlocked(),但首先仔细阅读它的作用

  2. 使用 fgetc() 或 fgetc_unlocked() 而不是 fgets() 获取数据。使用 fgets(),您的数据会被复制到内存中两次,首先由 C 运行时库从文件复制到内部缓冲区(流 I/O 被缓冲),然后从该内部缓冲区复制到程序中的数组

读取一气呵成整个文件到缓冲区中。

过程从该缓冲器的行。

这是最快的可能的解决方案。

您可以尝试通过读取大量数据到RAM中,然后在该工作最大限度地减少你的开支从磁盘读取时间。从磁盘读取速度很慢,所以通过读取(理想)整个文件一次,然后在其上工作尽量减少你花在做那个时间。

八九不离十像这样CPU缓存最大限度地减少了CPU要追溯到RAM的时候,你可以使用RAM,以尽量减少次数,你真正去到磁盘。

根据环境的不同,使用setvbuf用来()以增加由文件流使用可能会或可能不会提高性能的内部缓冲器的大小。

这是语法 -

setvbuf (InputFile, NULL, _IOFBF, BUFFER_SIZE);

其中INPUTFILE是FILE *只使用fopen()和BUFFER_SIZE打开的文件是缓冲器(这是由该呼叫为你分配)的大小。

您可以尝试各种缓冲区大小,看看是否有任何积极的影响。请注意,这是完全可选的,和你的运行可能与此有关的呼叫绝对没有。

如果将数据从磁盘来,可以是IO的约束。

如果是这样的话,获得更快的磁盘(但首先应该检查你得到最有效地利用现有的一...一些Linux发行不优化的开箱(hdparm)的磁盘访问),级中的数据到存储器中(比如将其复制到RAM盘)的提前,或准备等待。


如果你没有IO约束,你可能会浪费很多时间复制。你可以受益于所谓的零拷贝的方法。像存储器的东西映射文件,只通过指针来访问它。

这是一个有点超出我的专长,所以你应该做一些阅读或等待更多的知识渊博的帮助。

BTW--你可能会得到比成问题更多的工作是值得;也许更快的机器将解决所有的问题...

NB--目前尚不清楚,可以存储器映射标准输入要么...

考查的fread()。它读取我快得多,特别是如果FREAD缓冲区设置为65536。缺点:你必须做大量的工作,基本上编写自己的getline函数的从二进制读转换为文本。 检查出:文件I / O

如果操作系统支持的话,你可以尝试异步文件读取,也就是说,该文件被读入内存而CPU是忙于做其他事情。所以,代码都类似:

start asynchronous read
loop:
  wait for asynchronous read to complete
  if end of file goto exit
  start asynchronous read
  do stuff with data read from file
  goto loop
exit:

如果你有一个以上的CPU然后一个CPU读取该文件,所述数据解析成线,其他CPU占用每一行,并对其进行处理。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top