我如何避免更改堆栈大小,并避免让C#中的堆栈溢出 [英] How do I avoid changing the Stack Size AND avoid getting a Stack Overflow in C#

查看:547
本文介绍了我如何避免更改堆栈大小,并避免让C#中的堆栈溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直想现在找了几个小时的回答这个问题,在网络上,并在这个网站,我不太有。

I've been trying to find an answer to this question for a few hours now on the web and on this site, and I'm not quite there.

据我所知,.NET 1MB分配给应用程序,而且它的最好重新编码,而不是强迫的堆栈大小,以避免堆栈溢出。

I understand that .NET allocates 1MB to apps, and that it's best to avoid stack overflow by recoding instead of forcing stack size.

我工作的一个最短路径的应用程序,以约3000个节点,此时它溢出的伟大工程的。下面是导致问题的方法:

I'm working on a "shortest path" app that works great up to about 3000 nodes, at which point it overflows. Here's the method that causes problems:

    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

有关参考, Node类有一个成员:

For reference, the Node class has one member:

 public Dictionary<int, int> edges = new Dictionary<int, int>();



图[]是​​:

graph[] is:

  private Dictionary<int, Node> graph = new Dictonary<int, Node>();



我试图opimize使得它没有携带比需要更多的行李码一个迭代(递归?)到下一个,但具有1-9之间的边缘它会很快打的1MB限制每个节点的100K-节点图。

I've tried to opimize the code so that it isn't carrying any more baggage than needed from one iteration (recursion?) to the next, but with a 100K-Node graph with each node having between 1-9 edges it's going to hit that 1MB limit pretty quickly.

无论如何,我是新的C#和代码优化,如果有人可以给我一些指点(的不喜欢这个)我将不胜感激。

Anyway, I'm new to C# and code optimization, if anyone could give me some pointers (not like this) I would appreciate it.

推荐答案

前阵子我探讨了这个问题在我的博客。或者说,我摸索出了相关的问题:你如何找到一个二叉树的深度,而无需使用递归?递归树的深度解决方案是小事,但吹如果树是高度不平衡的堆栈。

A while back I explored this problem in my blog. Or, rather, I explored a related problem: how do you find the depth of a binary tree without using recursion? A recursive tree depth solution is trivial, but blows the stack if the tree is highly imbalanced.

我的建议是研究解决这个简单问题的方式,然后决定哪些其中,如果有的话,可以适应您的稍微复杂的算法。

My recommendation is to study ways of solving this simpler problem, and then decide which of them, if any, could be adapted to your slightly more complex algorithm.

请注意,在这些文章中的例子给出了完全在JScript中。但是,它不应该是很难使之适应于C#。

Note that in these articles the examples are given entirely in JScript. However, it should not be difficult to adapt them to C#.

下面我们开始定义的问题。

Here we start by defining the problem.

的http://博客.msdn.com / ericlippert /存档/ 2005/07/27 /递归部分 - 一个递归数据结构和-functions.aspx

在溶液中的第一次尝试是典型的技术,你可能会采取:定义一个明确的协议栈;使用它,而不是依赖于操作系统和编译器执行堆栈为您服务。这就是当面对这个问题大多数人做的。

The first attempt at a solution is the classic technique that you'll probably adopt: define an explicit stack; use it rather than relying upon the operating system and compiler implementing the stack for you. This is what most people do when faced with this problem.

http://blogs.msdn.com/ericlippert/archive/2005/08/01/recursion-part - 两个 - 展开 - 一个递归函数与 - 一个显式-stack.aspx

与解决方案的问题是,它是有点一团糟。我们可以去更远不是简单地使我们自己的堆栈。我们可以使我们自己的小领域特定的虚拟机都有自己的堆分配栈,然后通过编写一个程序,它针对该机器解决问题!这是比它听起来其实更容易;机器的操作可能会非常高的水平。

The problem with that solution is that it's a bit of a mess. We can go even farther than simply making our own stack. We can make our own little domain-specific virtual machine that has its own heap-allocated stack, and then solve the problem by writing a program that targets that machine! This is actually easier than it sounds; the operations of the machine can be extremely high level.

http://blogs.msdn.com/ericlippert/archive/2005/08/04/recursion-part-three-building-a-dispatch- engine.aspx

最后,如果你真的惩罚一个馋嘴(或编译器的开发者),你可以在继续改写程序传球方式,从而消除了对堆栈的需要在所有的

And finally, if you are really a glutton for punishment (or a compiler developer) you can rewrite your program in Continuation Passing Style, thereby eliminating the need for a stack at all:

http://blogs.msdn.com/ericlippert/archive/2005/08/08/recursion-part-four-continuation-passing-style.aspx

http://blogs.msdn.com/ericlippert/archive/2005/08/11/recursion-part-five-more-on-cps.aspx

HTTP: //blogs.msdn.com/ericlippert/archive/2005/08/15/recursion-part-six-making-cps-work.aspx

CPS是由一群代表之间的关系,其编码移动隐含的堆栈数据结构关闭系统堆栈和到堆上的一个特别聪明的办法。

CPS is a particularly clever way of moving the implicit stack data structure off the system stack and onto the heap by encoding it in the relationships between a bunch of delegates.

下面是我所有的递归文章:

Here are all of my articles on recursion:

http://blogs.msdn.com/ericlippert/archive/tags/Recursion/default.aspx

这篇关于我如何避免更改堆栈大小,并避免让C#中的堆栈溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆