如何快速计算线?

我尝试了unxutils的wc -l但它崩溃了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 / 4秒= 125MB / s已经非常快。 获得更快速度的唯一方法是通过RAID或使用SSD,而不是通过更好的算法。

File.ReadLines是在.NET 4.0中引入的

 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  #include  #include  void Usage(char *appname) { printf("\nLineCount.exe\n"); printf(" count lines in a text file...\n\n"); printf("usage:\n"); printf(" %s \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上的输入并输出行数。