Analizzando l'allocazione di memoria .NET del mio codice con la procedura guidata di prestazioni di Visual Studio 2013 ho notato una certa funzione di assegnazione di un sacco di byte (dal momento che è chiamato in un ciclo di grandi dimensioni). Ma guardando la funzione evidenziata nel rapporto di profilazione non ho capito perché stia allocando alcun tipo di memoria.non esecuzione di LINQ che causano l'allocazione di memoria C#
Per capire meglio quello che è successo ho isolato il codice che causa le allocazioni. Questo era simile alla classe LinqAllocationTester di seguito.
volta ho commentato il codice LINQ in quella funzione, mai eseguito comunque nel percorso codice testato, nessuna memoria è stato allocato più. La classe NonLinqAllocationTester imita questo comportamento. Sostituendo il codice LINQ con un ciclo normale, non è consentito allocare alcuna memoria.
Se eseguo il test di allocazione della memoria .NET sul codice di test sottostante, viene indicato che LinqAllocationTester causa 100.000 allocazioni (1 per chiamata), mentre NonLinqAllocationTester non ne ha. Nota che useLinq è sempre falso, quindi il codice LINQ non viene mai effettivamente eseguito.
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
Allora perché la non esecuzione di LINQ allocazioni di codice di causa di memoria? E c'è un modo per evitare questo oltre ad evitare le funzioni LINQ?
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;
}
}
}