如何快速计算行数?

| 我尝试了unxutils \'0',但是它崩溃了1GB文件。我尝试了此C#代码
long count = 0;
using (StreamReader r = new StreamReader(f))
{
    string line;
    while ((line = r.ReadLine()) != null)
    {
        count++;
    }
}

return count;
它在4秒钟内读取500MB文件
var size = 256;
var bytes = new byte[size];
var count = 0;
byte query = Convert.ToByte(\'\\n\');
using (var stream = File.OpenRead(file))
{
    int many;
    do
    {
        many = stream.Read(bytes, 0, size);
        count += bytes.Where(a => a == query).Count();                    
    } while (many == size);
}
10秒内读取
var count = 0;
int query = (int)Convert.ToByte(\'\\n\');
using (var stream = File.OpenRead(file))
{
    int current;
    do
    {
        current = stream.ReadByte();
        if (current == query)
        {
            count++;
            continue;
        }
    } while (current!= -1);
}
需要7秒 我还没有尝试过更快的速度吗?     
已邀请:
您的第一种方法确实看起来像是最佳解决方案。请记住,您几乎不受CPU限制,但受HD的读取速度限制,以500MB / 4sec = 125MB / s的速度已经相当快了。比RAID更快的唯一方法是通过RAID或使用SSD,而不是通过更好的算法。     
.NET 4.0中引入了ѭ4
var count = File.ReadLines(file).Count();
与第一个代码段相同的时间为4秒     
您是否只是在寻找一种工具来高效地计算文件中的行数?如果是这样,请尝试使用MS LogParser 如下所示将给您几行:
LogParser \"SELECT count(*) FROM file\" -i:TEXTLINE
    
如果您真的想要快速,请考虑使用C代码。 如果这是命令行实用程序,它将更快,因为它不必初始化CLR或.NET。而且,它不会为从文件中读取的每一行重新分配新的字符串,这可能节省了吞吐量。 我没有1g行的文件,因此无法比较。您可以尝试,但是:
/*
 * LineCount.c
 *
 * count lines...
 *
 * compile with: 
 *
 *  c:\\vc10\\bin\\cl.exe /O2 -Ic:\\vc10\\Include -I\\winsdk\\Include 
 *          LineCount.c -link /debug /SUBSYSTEM:CONSOLE /LIBPATH:c:\\vc10\\Lib
 *          /LIBPATH:\\winsdk\\Lib /out:LineCount.exe
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


void Usage(char *appname)
{
    printf(\"\\nLineCount.exe\\n\");
    printf(\"  count lines in a text file...\\n\\n\");
    printf(\"usage:\\n\");
    printf(\"  %s <filename>\\n\\n\", appname);
}



int linecnt(char *file)
{
    int sz = 2048;
    char *buf = (char *) malloc(sz);
    FILE *fp = NULL;
    int n= 0;
    errno_t rc = fopen_s(&fp, file, \"r\");

    if (rc) {
        fprintf(stderr, \"%s: fopen(%s) failed: ecode(%d)\\n\",
                __FILE__, file, rc);
        return -1;
    }

    while (fgets(buf, sz, fp)){
        int r = strlen(buf);
        if (buf[r-1] == \'\\n\')
            n++;
        // could re-alloc here to handle larger lines
    }
    fclose(fp);
    return n;
}

int main(int argc, char **argv)
{
    if (argc==2) {
        int n = linecnt (argv[1]);
        printf(\"Lines: %d\\n\", n);
    }
    else {
        Usage(argv[0]);
        exit(1);
    }
}
    
我认为您的回答看起来不错。我唯一要添加的就是播放缓冲区大小。我觉得这可能会改变性能,具体取决于您的缓冲区大小。 请在以下位置参考缓冲区大小-最佳文件缓冲区读取大小?     
您尝试过flex吗?
%{
long num_lines = 0;
%}
%option 8bit outfile=\"scanner.c\"
%option nounput nomain noyywrap
%option warn

%%
.+ { }
\\n { ++num_lines; }
%%
int main(int argc, char **argv);

int main (argc,argv)
int argc;
char **argv;
{
yylex();
printf( \"# of lines = %d\\n\", num_lines );
return 0;
}
只需编译:
flex -Cf scanner.l 
gcc -O -o lineCount.exe scanner.c
它接受stdin上的输入并输出行数。     

要回复问题请先登录注册