13

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

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

4

7 回答 7

8

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

于 2009-04-09T14:31:09.527 回答
4
  1. 使用 fgets_unlocked(),但先仔细阅读它的作用

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

于 2009-04-09T14:26:48.040 回答
4

一口气将整个文件读入缓冲区。

处理该缓冲区中的行。

这是最快的解决方案。

于 2009-04-09T14:30:48.747 回答
3

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

类似于 CPU 缓存最小化 CPU 实际返回 RAM 的时间的方式,您可以使用 RAM 来最小化实际进入磁盘的次数。

于 2009-04-09T01:43:26.923 回答
2

如果数据来自磁盘,您可能会受到 IO 限制。

如果是这种情况,请获得更快的磁盘(但首先检查您是否充分利用了现有磁盘......某些 Linux 发行版没有优化开箱即用的磁盘访问(hdparm)),将数据暂存到提前内存(比如将其复制到 RAM 磁盘),或者准备等待。


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

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

顺便说一句——你可能会投入比问题价值更多的工作;也许更快的机器会解决你所有的问题......

NB-- 尚不清楚您是否可以对标准输入进行内存映射...

于 2009-04-09T01:28:20.767 回答
2

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

这是语法 -

setvbuf (InputFile, NULL, _IOFBF, BUFFER_SIZE);

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

您可以尝试各种缓冲区大小,看看是否有积极影响。请注意,这完全是可选的,您的运行时可能对这个调用完全没有任何作用。

于 2009-04-09T07:13:04.820 回答
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 获取每一行并处理它。

于 2009-04-29T14:41:58.170 回答