में स्टैक ओवरफ़्लो प्राप्त करने से बचने के लिए मैं वेब पर और इस साइट पर कुछ घंटों के लिए इस प्रश्न का उत्तर ढूंढने का प्रयास कर रहा हूं, और मैं काफी नहीं हूं क्या आप वहां मौजूद हैं।मैं स्टैक आकार को बदलने से कैसे बच सकता हूं और सी #
मैं समझता हूं कि .NET ऐप्स को 1 एमबी आवंटित करता है, और स्टैक आकार को मजबूर करने के बजाय रिकोडिंग द्वारा स्टैक ओवरफ़्लो से बचना सर्वोत्तम होता है।
मैं एक "सबसे छोटा रास्ता" ऐप पर काम कर रहा हूं जो लगभग 3000 नोड्स तक बढ़िया काम करता है, जिस बिंदु पर यह बहती है। यहाँ विधि है कि समस्याओं का कारण बनता है:
public Dictionary<int, int> edges = new Dictionary<int, int>();
ग्राफ [] है:
private Dictionary<int, Node> graph = new Dictonary<int, Node>();
मैं opimize करने की कोशिश की है
public void findShortestPath(int current, int end, int currentCost)
{
if (!weight.ContainsKey(current))
{
weight.Add(current, currentCost);
}
Node currentNode = graph[current];
var sortedEdges = (from entry in currentNode.edges orderby entry.Value ascending select entry);
foreach (KeyValuePair<int, int> nextNode in sortedEdges)
{
if (!visited.ContainsKey(nextNode.Key) || !visited[nextNode.Key])
{
int nextNodeCost = currentCost + nextNode.Value;
if (!weight.ContainsKey(nextNode.Key))
{
weight.Add(nextNode.Key, nextNodeCost);
}
else if (weight[nextNode.Key] > nextNodeCost)
{
weight[nextNode.Key] = nextNodeCost;
}
}
}
visited.Add(current, true);
foreach (KeyValuePair<int, int> nextNode in sortedEdges)
{
if(!visited.ContainsKey(nextNode.Key) || !visited[nextNode.Key]){
findShortestPath(nextNode.Key, end, weight[nextNode.Key]);
}
}
}//findShortestPath
संदर्भ के लिए, नोड वर्ग एक सदस्य है कोड ताकि वह एक पुनरावृत्ति (रिकर्सन?) से अगले की आवश्यकता के मुकाबले और अधिक सामान नहीं ले रहा है, लेकिन 100-नोड ग्राफ़ के साथ प्रत्येक नोड के साथ 1-9 किनारों के बीच होता है, यह 1 एमबी सीमा को बहुत तेज़ी से मारने जा रहा है।
वैसे भी, मैं सी # और कोड अनुकूलन के लिए नया हूं, अगर कोई मुझे कुछ पॉइंटर्स दे सकता है (not like this) मैं इसकी सराहना करता हूं।
या ... आप सुनिश्चित कर सकते हैं कि आपके एल्गोरिदम को सीएलआर द्वारा पूंछ रिकर्सिव रूप में परिवर्तित किया जा सके। – LBushkin
सी # कभी tailcall निर्देश उत्पन्न नहीं करता है। जिटर के कुछ संस्करणों से पता चलेगा कि टेलिकल रिकर्सन का उपयोग करके एक विशेष विधि को अनुकूलित किया जा सकता है भले ही टेलकॉल निर्देश का उपयोग न किया जाए। हालांकि, हमारे द्वारा जारी किए गए अधिकांश झटके में यह अनुकूलन नहीं है, और आपको इसका भरोसा नहीं करना चाहिए। –
और इसके अलावा, आपकी सलाह वास्तव में क्रियाशील नहीं है। * कैसे * वास्तव में मूल पोस्टर होना चाहिए "सुनिश्चित करें कि एल्गोरिदम को पूंछ रिकर्सिव रूप में परिवर्तित किया जा सकता है"? यह एक जटिल प्रक्रिया है जिसके लिए रनटाइम के कार्यान्वयन विवरण की गहरी समझ की आवश्यकता होती है, यह समझते हुए कि मैं 42 के निर्माण में लोगों के अलावा किसी और की अपेक्षा नहीं करता हूं। –