我在C#中编写了一个应用程序,它生成了字母,数字和少数特殊字符组合中可以存在的所有单词。
问题在于它不具有内存效率,因为它正在调整Recursion以及一些像List这样的集合。
有什么方法可以让它在有限的内存环境中运行?
Umair
答案 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#中生成字符串时,它会占用自己的内存并可能会暂停一段时间。如果您生成数百万个字符串,则可能会发现性能拖累。
如果您不需要保留许多字符串,我会看到是否存在以避免生成字符串。例如,您可能有一个字符数组,当您在字符组合中移动时会不断更新,如果您将它们输出到文件,您可以一次输出一个字符,这样您就不必构建字符串。