昨天和別人討論了一下linq的效能,自我覺得linq的效能不行,但是實際上linq還是在效能上有過人之處的,linq to sql除外,以下是簡單的效能測試比較代碼,在這裡解釋一下,代碼的執行速度計時測試不能用datetime了,我還是個小白,剛開始用的datetime,結果發現linq的效能並不行,但是用StopWatch才發現了事實,以前對linq的偏見的同學還是擁抱一下linq吧,也許某些方面還存在沒完全理解透,還請園友們給予批評指正。
class Program
{
static void Main(string[] args)
{
test();
}
static void test()
{
List<MyClass> list1 = new List<MyClass>();
for (int i = 0; i < 10000000; i++)
{
MyClass aa=new MyClass();
aa.Name = "測試資料" + i;
aa.id = i;
list1.Add(aa);
}
Stopwatch timer = new Stopwatch();
#region for迴圈
timer.Start();
List<MyClass> list2 = new List<MyClass>();
foreach (MyClass s in list1)
{
if (s.id >= 52 && s.id < 850) { list2.Add(s); }
}
timer.Stop();
Console.Write("集合匹配數" + list2.Count + ",for迴圈耗時:");
Console.WriteLine(timer.Elapsed.Ticks);
#endregion
#region linq
timer = new Stopwatch();
timer.Start();
var list3 = list1.Where(product => product.id >= 52 && product.id < 850);
timer.Stop();
Console.Write("集合匹配數" + list3.Count() + ",linq耗時:");
Console.WriteLine(timer.Elapsed.Ticks);
#endregion
#region delegate
timer = new Stopwatch();
timer.Start();
List<MyClass> list4 = list1.FindAll(delegate(MyClass post)
{
return post.id >= 52 && post.id < 850;
});
timer.Stop();
Console.Write("集合匹配數" + list4.Count() + ",delegate耗時:");
Console.WriteLine(timer.Elapsed.Ticks);
#endregion
Console.Read();
}
public class MyClass
{
public string Name { get; set; }
public int id { get; set; }
}
}
測試的效果如下:
如果理解的不正確,還請大家批評一下,不能讓錯誤的思想誤人子弟
根據園友的批評指正,重新整理了一下代碼,雖然是個簡單的東西,但是對於新手批評比裝懂好,對園友的細心指正不勝感激。
重新整理的代碼如下:
View Code
class Program
{
static void Main(string[] args)
{
test();
}
static void test()
{
List<MyClass> list1 = new List<MyClass>();
for (int i = 0; i < 10000000; i++)
{
MyClass aa=new MyClass();
aa.Name = "測試資料" + i;
aa.id = i;
list1.Add(aa);
}
Stopwatch timer = new Stopwatch();
#region for迴圈
timer.Start();
List<MyClass> list2 = new List<MyClass>();
int count = 0;
foreach (MyClass s in list1)
{
if (s.id >= 52 && s.id < 850) { list2.Add(s); }
}
count = list2.Count;
timer.Stop();
Console.Write("集合匹配數" + count + ",for迴圈耗時:");
Console.WriteLine(timer.Elapsed.Ticks);
#endregion
#region linq
timer = new Stopwatch();
timer.Start();
var list3 = list1.Where(product => product.id >= 52 && product.id < 850);
//list1.Where(product => product.id >= 52 && product.id < 850).ToArray().Count();
int count3 = list3.Count();
timer.Stop();
Console.Write("集合匹配數" + count3 + ",linq耗時:");
Console.WriteLine(timer.Elapsed.Ticks);
#endregion
#region delegate
timer = new Stopwatch();
timer.Start();
List<MyClass> list4 = list1.FindAll(delegate(MyClass post)
{
return post.id >= 52 && post.id < 850;
});
int count4 = list4.Count();
timer.Stop();
Console.Write("集合匹配數" + count4 + ",delegate耗時:");
Console.WriteLine(timer.Elapsed.Ticks);
#endregion
Console.Read();
}
public class MyClass
{
public string Name { get; set; }
public int id { get; set; }
}
}
測試
第三次更新代碼,這次沒有先後順序產生的問題了:
View Code
class Program
{
static void Main(string[] args)
{
List<MyClass> list1 = new List<MyClass>();
for (int i = 0; i < 10000000; i++)
{
MyClass aa = new MyClass();
aa.Name = "測試資料" + i;
aa.id = i;
list1.Add(aa);
}
test_linq(list1);
test_foreach(list1);
test_delegate(list1);
Console.Read();
}
static void test_foreach(List<MyClass> list1)
{
Stopwatch timer = new Stopwatch();
#region foreach迴圈
timer.Start();
List<MyClass> list2 = new List<MyClass>();
int count = 0;
foreach (MyClass s in list1)
{
if (s.id >= 52 && s.id < 850) { list2.Add(s); }
}
count = list2.Count;
timer.Stop();
Console.Write("集合匹配數" + count + ",for迴圈耗時:");
Console.WriteLine(timer.Elapsed.Ticks);
#endregion
}
static void test_linq(List<MyClass> list1)
{
Stopwatch timer = new Stopwatch();
#region linq
timer = new Stopwatch();
timer.Start();
var list3 = list1.Where(product => product.id >= 52 && product.id < 850);
//list1.Where(product => product.id >= 52 && product.id < 850).ToArray().Count();
int count3 = list3.Count();
timer.Stop();
Console.Write("集合匹配數" + count3 + ",linq耗時:");
Console.WriteLine(timer.Elapsed.Ticks);
#endregion
}
static void test_delegate(List<MyClass> list1)
{
Stopwatch timer = new Stopwatch();
#region delegate
timer = new Stopwatch();
timer.Start();
List<MyClass> list4 = list1.FindAll(delegate(MyClass post)
{
return post.id >= 52 && post.id < 850;
});
int count4 = list4.Count();
timer.Stop();
Console.Write("集合匹配數" + count4 + ",delegate耗時:");
Console.WriteLine(timer.Elapsed.Ticks);
#endregion
}
public class MyClass
{
public string Name { get; set; }
public int id { get; set; }
}
}
看以上基本沒什麼大的變化
總結:沒有認識linq在延時載入方面的處理,所以linq的count操作觸發了linq的實際查詢操作,也許還沒有深入理解,但是總有一天會理解的
部落格地址:http://www.jqpress.com/post/43.aspx