[英]Fastest way to count lines in file in MATLAB (Perl faster than C?)
[英]Fastest way to count number of lines?
計算文件中行號的最簡單方法是:
while(!feof(fp))
{
ch = fgetc(fp);
if(ch == '\n')
{
lines++;
}
}
但現在要求是我必須計算大文件中的行數。 它會對性能產生影響。
有更好的方法嗎?
對於最快的I / O,通常需要讀取/寫入文件系統/ OS的塊大小的倍數。
您可以通過在文件或文件描述符上調用statfs
或fstatfs
來查詢塊大小(請參閱手冊頁)。
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;
}
現在分配該大小的緩沖區並讀取(使用read
或fread
)該大小的塊。 然后迭代這個內存中的塊並計算換行數。 重復直到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.