विजुअल स्टूडियो 2013 प्रदर्शन विज़ार्ड के साथ मेरे कोड के .NET स्मृति आवंटन का विश्लेषण करते समय मैंने कई बाइट आवंटित करने के लिए एक निश्चित फ़ंक्शन देखा (क्योंकि इसे बड़े लूप में कहा जाता है)। लेकिन प्रोफाइलिंग रिपोर्ट में हाइलाइट किए गए फ़ंक्शन को देखते हुए मुझे समझ में नहीं आया कि यह किसी भी स्मृति को आवंटित क्यों कर रहा था।स्मृति निष्पादन के कारण गैर निष्पादन linq सी #
बेहतर समझने के लिए कि क्या हुआ, मैंने आवंटन के कारण कोड को अलग कर दिया। यह नीचे LinqAllocationTester वर्ग के समान था।
एक बार जब मैंने उस फ़ंक्शन में LINQ कोड पर टिप्पणी की, जिसे परीक्षण कोड पथ में कभी भी निष्पादित नहीं किया गया था, अब कोई स्मृति आवंटित नहीं की गई थी। NonLinqAllocationTester कक्षा इस व्यवहार का अनुकरण करती है। सामान्य लूप के साथ LINQ कोड को प्रतिस्थापित करने से स्मृति आवंटन भी नहीं हो जाता है।
यदि मैं नीचे दिए गए टेस्ट कोड पर .NET स्मृति आवंटन परीक्षण चलाता हूं तो यह दिखाता है कि LinqAllocationTester 100.000 आवंटन (1 प्रति कॉल) का कारण बनता है, जबकि NonLinqAllocationTester में कोई नहीं है। ध्यान दें कि लिनक का उपयोग हमेशा झूठा होता है, इसलिए LINQ कोड को वास्तव में कभी भी निष्पादित नहीं किया जा रहा है।
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
तो क्यों करता है गैर LINQ कोड कारण स्मृति आवंटन को क्रियान्वित? और क्या 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;
}
}
}