比fgets更快地读取输入线?

时间:2009-04-09 01:24:34

标签: c optimization file-io stdin fgets

我正在编写一个程序,其中性能非常重要,但并不重要。目前我正逐行阅读FILE*的文字,我使用fgets获取每一行。使用了一些性能工具后,我发现应用程序运行的时间占20%到30%,它位于fgets内。

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

8 个答案:

答案 0 :(得分:7)

你没有说你在哪个平台上,但如果它是类似UNIX的,那么你可能想尝试read()系统调用,它不会执行额外的缓冲层fgets()等做。这可能会稍微加快速度,另一方面它可能会减慢速度 - 找出答案的唯一方法就是吸收并看到它。

答案 1 :(得分:4)

  1. 使用fgets_unlocked(),但仔细阅读它的内容

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

答案 2 :(得分:4)

将所有文件一次性读入缓冲区。

处理该缓冲区中的行。

这是最快的解决方案。

答案 3 :(得分:3)

您可以尝试通过将大量数据读入RAM然后进行处理来最小化从磁盘读取的时间。从磁盘读取速度很慢,因此通过一次读取(理想情况下)整个文件,然后对其进行处理,可以最大限度地减少花费的时间。

Sorta就像CPU缓存最小化CPU实际返回RAM的时间一样,您可以使用RAM来最小化实际进入磁盘的次数。

答案 4 :(得分:2)

如果数据来自磁盘,则可能是IO绑定。

如果是这种情况,请获取更快的磁盘(但首先检查您是否正在充分利用现有的磁盘......某些Linux发行版不会优化磁盘访问开箱即用({{1} })),将数据提前存储(例如将其复制到RAM磁盘),或准备等待。


如果你不受IO约束,你可能会浪费大量时间复制。您可以从所谓的零复制方法中受益。像内存这样的东西映射文件,只能通过指针访问它。

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

顺便说一句,你可能会比问题值得做更多的工作;也许更快的机器可以解决你所有的问题......

注意 - 目前尚不清楚您是否可以将标准输入存储在地图中......

答案 5 :(得分:2)

根据您的环境,使用setvbuf()增加文件流使用的内部缓冲区的大小可能会也可能不会提高性能。

这是语法 -

setvbuf (InputFile, NULL, _IOFBF, BUFFER_SIZE);

其中InputFile是刚刚使用fopen()打开的文件的FILE *,BUFFER_SIZE是缓冲区的大小(由此调用为您分配)。

您可以尝试各种缓冲区大小,看看是否有任何积极影响。请注意,这完全是可选的,并且您的运行时可能无法完成此调用。

答案 6 :(得分:0)

如果操作系统支持它,你可以尝试异步文件读取,也就是说,当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占用每行并处理它。

答案 7 :(得分:0)

查看fread()。它对我来说读起来要快得多,特别是如果fread的缓冲区设置为65536.缺点:你必须做很多工作,基本上编写自己的getline函数来从二进制读取转换为文本。 查看:file I/O