Visual Studio 2013 performans sihirbazla kodumun .NET bellek ayırma çözümlenirken, bir çok bayt ayırma belirli bir işlev olduğunu fark ettim (büyük bir döngüde çağrıldığı için). Ancak profilleme raporunda vurgulanan işleve bakmak, neden hiç bellek ayırdığını anlamadım.nonquting linq neden bellek ayırma C#
Neyin yaşandığını daha iyi anlamak için, tahsisatlara neden olan kodu izole ettim. Bu, aşağıdaki LinqAllocationTester sınıfına benzerdi. Test kod yolunda hiçbir zaman çalıştırılmamış olan bu işlevdeki LINQ kodunu bir kez daha açıkladım, artık bir bellek ayrılmadı. NonLinqAllocationTester sınıfı bu davranışı taklit eder. LINQ kodunu normal bir döngü ile değiştirmek, ayrıca bellek ayırmalarına izin vermez.
.NET bellek ayırma sınamasını aşağıdaki sınama kodunda çalıştırırsam, LinqAllocationTester'ın 100.000 ayırmaya (çağrı başına 1) neden olduğunu gösterirken NonLinqAllocationTester öğesinin hiçbiri yoktur. UseLinq öğesinin her zaman false olduğunu unutmayın, bu nedenle LINQ kodunun kendisi gerçekte yürütülmez.
Function Name | Inclusive | Exclusive | Inclusive | Exclusive
| Allocations | Allocations | Bytes | Bytes
-------------------------------------------------------------------------------------
LinqAllocationTester.Test(int32) | 100.000 | 100.000 | 1.200.000 | 1.200.000
Program.Main(string[]) | 100.000 | 0 | 1.200.000 | 0
Peki neden yapar LINQ kod neden bellek ayırmalarını infaz non? LINQ fonksiyonlarından kaçınmanın yanı sıra bunu engellemenin bir yolu var mı?
class Program {
static void Main(string[] args) {
List<int> values = new List<int>() { 1, 2, 3, 4 };
LinqAllocationTester linqTester = new LinqAllocationTester(false, values);
NonLinqAllocationTester nonLinqTester = new NonLinqAllocationTester(false, values);
for (int i = 0; i < 100000; i++) {
linqTester.MaxDifference(i);
}
for (int i = 0; i < 100000; i++) {
nonLinqTester.MaxDifference(i);
}
}
}
internal class LinqAllocationTester {
private bool useLinq;
private List<int> values;
public LinqAllocationTester(bool useLinq, List<int> values) {
this.useLinq = useLinq;
this.values = values;
}
public int MaxDifference(int value) {
if (useLinq) {
return values.Max(x => Math.Abs(value - x));
} else {
int maxDifference = int.MinValue;
foreach (int value2 in values) {
maxDifference = Math.Max(maxDifference, Math.Abs(value - value2));
}
return maxDifference;
}
}
}
internal class NonLinqAllocationTester {
private bool useLinq;
private List<int> values;
public NonLinqAllocationTester(bool useLinq, List<int> values) {
this.useLinq = useLinq;
this.values = values;
}
public int MaxDifference(int value) {
if (useLinq) {
return 0;
} else {
int maxDifference = int.MinValue;
foreach (int value2 in values) {
maxDifference = Math.Max(maxDifference, Math.Abs(value - value2));
}
return maxDifference;
}
}
}