簡體   English   中英

計算行數的最快方法?

[英]Fastest way to count number of lines?

計算文件中行號的最簡單方法是:

while(!feof(fp))
{
  ch = fgetc(fp);
  if(ch == '\n')
  {
    lines++;
  }
}

但現在要求是我必須計算大文件中的行數。 它會對性能產生影響。

有更好的方法嗎?

對於最快的I / O,通常需要讀取/寫入文件系統/ OS的塊大小的倍數。

您可以通過在文件或文件描述符上調用statfsfstatfs來查詢塊大小(請參閱手冊頁)。

struct statfs有一個字段f_bsize ,有時也有f_iosize

最佳傳輸塊大小

f_bsize字段存在於所有POSIX系統AFAIK上。 在Mac OS X和iOS上,還有f_iosize ,這是你在這些平台上的首選(但f_bsize可以在Mac OS X / iOS上運行,通常應與f_iosize ,IIRC相同)。

struct statfs fsInfo = {0};
int fd = fileno(fp); // Get file descriptor from FILE*.
long optimalSize;

if (fstatfs(fd, &fsInfo) == -1) {
    // Querying failed! Fall back to a sane value, for example 8kB or 4MB.
    optimalSize = 4 * 1024 * 1024;
} else {
    optimalSize = fsInfo.f_bsize;
}

現在分配該大小的緩沖區並讀取(使用readfread )該大小的塊。 然后迭代這個內存中的塊並計算換行數。 重復直到EOF。

另一種方法是@Ioan提出的方法:使用mmap將文件映射到內存並迭代該緩沖區。 這可能會為您提供最佳性能,因為內核可以以最有效的方式讀取數據,但是對於“太大”的文件,這可能會失敗,而我上面描述的方法總是適用於任意大小的文件並且讓您靠近 - 最佳性能。

“有更好的方法嗎?”

使用!feof(fp)作為終止條件並不是一個好主意。 你最好的

while ((ch = fgetc(fp)) != EOF)

並檢查循環內的換行符(如上所述,考慮所有可能的換行符)。

更多信息: http//faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer = 1046476070&id = 1043284351

我建議嘗試使用內存映射IO來允許操作系統優化磁盤IO(可能是您最大的瓶頸),而您只需計算行數。 還可以考慮一條線可以用4種可能中的任何一種來表示:\\ r,\\ n,\\ r \\ n,文件結束。

除非文件不包含任何包含行號等元數據的標題,否則查找此數字具有線性復雜性。 另請注意“\\ n”不是通用換行符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM