如何快速计算行数
本文关键字:计算 何快速 | 更新日期: 2023-09-27 17:57:33
我尝试了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秒
我还没试过更快的吗?
File.ReadLines
是在中引入的。NET 4.0
var count = File.ReadLines(file).Count();
工作时间为4秒,与第一个代码片段
您的第一种方法看起来确实是最佳解决方案。请记住,您大多不受CPU限制,但受到HD读取速度的限制,500MB/4sec=125MB/s的读取速度已经相当快了。唯一比这更快的方法是通过RAID或使用SSD,而不是通过更好的算法。
您只是在寻找一种高效地计算文件中行数的工具吗?如果是,请尝试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上的输入并输出行数。