【原譯】四種方法統計字符串的行數&執行時間比較


免責申明(必讀!):本博客提供的所有教程的翻譯原稿均來自於互聯網,僅供學習交流之用,切勿進行商業傳播。同時,轉載時不要移除本申明。如產生任何糾紛,均與本博客所有人、發表該翻譯稿之人無任何關系。謝謝合作!

原文鏈接地址:http://www.codeproject.com/Tips/312312/Counting-lines-in-a-string

我需要統計一下字符串的行數,因此我就寫了一個超級沒有技術含量的蠻力方法來統計了。

static long LinesCount(string s)
{
long count = 0;
int position = 0;
while ((position = s.IndexOf('\n', position)) != -1)
{
count++;
position++; // Skip this occurance!
}
return count;
}


這個函數他呀,運行正常,寫起來也快。

但是,我就像啊,這是不是也太沒有技術含量了,難道就沒有其他方法了?

當然有,我想出了兩種方法:正則和Linq,我把這些方法都寫出來

static long LinesCountIndexOf(string s)
{
long count = 0;
int position = 0;
while ((position = s.IndexOf('\n', position)) != -1)
{
count++;
position++; // Skip this occurance!
}
return count;
}
static Regex r = new Regex("\n", RegexOptions.Multiline);
static long LinesCountRegex(string s)
{
MatchCollection mc = r.Matches(s);
return mc.Count;
}
static long LinesCountLinq(string s)
{
return (from ch in s
where ch== '\n'
select ch).Count();
}
static long LinesCountSplit(string s)
{
return (s.Split(new char[] { '\n' })).Length;
}

然后呢,我又寫了一個快速但混亂的毫無技術含量的測試程序來測試正確性

string s = File.ReadAllText(@"D:\Temp\MyLargeTextFile.txt");
long index = LinesCountIndexOf(s);
long regex = LinesCountRegex(s);
long linq= LinesCountLinq(s);
Console.WriteLine("{0}:{1}:{2}", index, regex, linq);
Stopwatch si = new Stopwatch();
Stopwatch sd = new Stopwatch();
Stopwatch sl = new Stopwatch();
Stopwatch ss = new Stopwatch();
si.Start();
for (int i = 0; i < 100; i++)
{
index = LinesCountIndexOf(s);
}
si.Stop();
ss.Start();
for (int i = 0; i < 100; i++)
{
index = LinesCountSplit(s);
}
ss.Stop();
sd.Start();
for (int i = 0; i < 100; i++)
{
index = LinesCountRegex(s);
}
sd.Stop();
sl.Start();
for (int i = 0; i < 100; i++)
{
index = LinesCountLinq(s);
}
sl.Stop();

輸入的文件是1.64Mb,包含大約23K行。

測試結果顯示是

22777:22777:22777

有意思的是這個執行時間的結果(ms計)

Test    ElapsedMilliseconds
BF+I 181
Split 1089
Regex 2557
Linq 3590

我本來想着這正則要快的不是一點點啊。正則和Linq這么大的差異令我震驚了,最令我震驚的是BF+I竟然比他們兩個都快,而分割則毫無疑問比Index要慢,因為在分割方法中.net一次要分配23k的字符串空間

為了完成任務,我把BF+I版本重寫了一個類,並且判斷了字符串只有一行的情況,如你期望的一樣,不要一秒就完成了

static class ExtensionMethods
{
/// <summary>
/// Returns the number of lines in a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static long Lines(this string s)
{
long count = 1;
int position = 0;
while ((position = s.IndexOf('\n', position)) != -1)
{
count++;
position++; // Skip this occurance!
}
return count;
}
}

注:count初始為1后,時間更短了一些。

Test    ElapsedMilliseconds
BF+I 170
Split 1089
Regex 2063
Linq 3583

完成。。
著作權聲明:本文由http://www.cnblogs.com/lazycoding翻譯,歡迎轉載分享。請尊重作者勞動,轉載時保留該聲明和作者博客鏈接,謝謝!



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM