Eqatec顯示了每次調用一個方法時都會調用幾千個匿名方法閉包,該方法在我的程序中包含一個簡單的LINQ'Where'語句。僞代碼示例:C#中過度匿名方法閉包(c__DisplayClass1)的原因是什麼?
Class1
{
//foo and bar are both EF model classes
List<foo> aList; // n = 2000
List<bar> bList; // n = ~4000
void aMethod()
{
foreach (var item in aList)
{
Class2.DoSomeWork(item, bList);
}
}
}
Class2
{
static void DoSomeWork(foo item, List<bar> bList)
{
var query = bList.where(x => x.prop1 == item.A && x.prop2 = item.B).toList(); // <--- Calls thousands of anonymous method closures each method call.
if (query.any()) <--- Calls only 1 anonymous method closure.
DoSomethingElse();
}
}
我不明白,爲什麼2000調用「DoSomeWork」叫約800萬匿名方法閉包(甚至1導致幾千個)。
作爲一個修復,我簡單地重寫了沒有使用LINQ的語句,從而消除了對閉包的需求,並將性能提高了10倍。
我仍然想知道爲什麼這發生在第一個地方,如果有人有一些他們想分享的理論。
你的意思是「創建8M對象」?還是你的意思是「調用方法8M次」?你發佈的代碼(在清理它之後編譯)***不會創建8M對象 - 它會導致2000,這是我們所期望的(通過'aList')。如果您指的是對象創建,我認爲您在複製/粘貼/清理期間已經更改了內容。我不認爲這種情況現在代表你所看到的。你可以發佈一些更接近原始的東西,理想情況下是a:編譯,而b:顯示問題? – 2012-08-14 07:02:13