记忆效率递归

时间:2010-07-28 22:16:03

标签: c# memory-management

我在C#中编写了一个应用程序,它生成了字母,数字和少数特殊字符组合中可以存在的所有单词。

问题在于它不具有内存效率,因为它正在调整Recursion以及一些像List这样的集合。

有什么方法可以让它在有限的内存环境中运行?

Umair

5 个答案:

答案 0 :(得分:8)

将其转换为iterative function.

答案 1 :(得分:1)

不幸的是,C#编译器不执行tail call optimization,这是您希望在这种情况下发生的事情。 CLR支持它,kinda,但你不应该依赖它。

也许只剩下字段,但也许你可以在F#中编写程序的递归部分?这样,您可以利用保证的尾调用优化和重用C#代码的位。虽然学习曲线陡峭,但F#对于这些组合任务来说是更合适的语言。

答案 2 :(得分:1)

嗯......我不确定我和谁在一起,但我得到了解决方案。我正在使用多个与用户交互的流程,以及其他用于查找单词组合的流程。另一个进程找到5000个单词,保存并退出。正在通过WCF实现沟通。当进程退出=释放内存时,这看起来非常精细。

答案 3 :(得分:0)

好吧,你显然无法将中间结果存储在内存中(除非你有一些荒谬的计算机可供你使用);你必须将结果写入磁盘。

递归深度不是所考虑字符数的结果 - 它取决于您愿意考虑的最大字符串长度。

例如,我安装的python 2.6.2将其默认递归限制设置为1000.可以说,我应该能够生成所有可能的1-1000长度字符串给定一个字符集在此限制内(现在,我认为递归限制适用于总堆栈深度,因此实际限制可能小于1000)。

编辑(添加了python示例): 以下python代码段将生成您要求的内容(将其自身限制为给定的运行时堆栈限制):

from string import ascii_lowercase

def generate(base="", charset=ascii_lowercase):
    for c in charset:
        next = base + c
        yield next
        try:
            for s in generate(next, charset):
                yield s
        except:
            continue

for s in generate():
    print s

通过在StackOverflowException上尝试/捕获,可以在C#中产生基本相同的东西。当我输入此更新时,脚本正在运行,咀嚼我的一个核心。但是,内存使用量不断超过7MB。现在,我只打印到stdout,因为我对捕获结果不感兴趣,但我认为它证明了上述观点。 ;)

示例附录: 有趣的说明:仔细观察正在运行的进程,python实际上是与上面的例子绑定的I / O.它只占我CPU的7%,而核心的其余部分则绑定在我的命令窗口中结果。最小化窗口允许python爬升到总CPU使用率的40%,这是在2核心机器上。

答案 4 :(得分:0)

还有一个注意事项:当您连接或使用其他方法在C#中生成字符串时,它会占用自己的内存并可能会暂停一段时间。如果您生成数百万个字符串,则可能会发现性能拖累。

如果您不需要保留许多字符串,我会看到是否存在以避免生成字符串。例如,您可能有一个字符数组,当您在字符组合中移动时会不断更新,如果您将它们输出到文件,您可以一次输出一个字符,这样您就不必构建字符串。