有一个奇怪的错误已经在 Mathematica 中存在多年,至少从 5.1 版本开始,并且一直存在到版本 7。
Module[{f, L}, L = f[];
Do[L = f[L, i], {i, 10^4}]] // Timing
{0.015, Null}
Module[{weirdness, L}, L = weirdness[];
Do[L = weirdness[L, i], {i, 10^4}]] // Timing
{2.266,空}
最佳答案
What causes this? Is it a hashing problem?
是的,或多或少。
Is it fixed in Version 8?
是的(也或多或少)。也就是说,不可能在任何“完整”意义上进行修复。但最常见的情况处理得更好。
Is there a way to know what symbol names cause a slowdown, other than testing?
我不知道。
在第 7 版中有一个与第 8 版中的修复类似的早期修复。默认情况下它是关闭的(我们在发布时没有足够的时间来测试它,并且它没有在 7.0 版中打开。 1)。可以按如下方式访问。
SetSystemOptions["NeedNotReevaluateOptions"->{"UseSymbolLists"->True}];
这使您的示例回到了合理的领域。
Module[{weirdness, L}, L = weirdness[];
Do[L = weirdness[L, i], {i, 10^4}]] // Timing
出[8]= {0.020997,空}
- -编辑 - -
我可以更详细地解释这里涉及的优化。首先回想一下 Mathematica 模拟“无限求值”,即表达式不断求值直到它们不再改变。这可能是昂贵的,因此需要仔细的短路优化以在可能的情况下阻止它。
我们使用的一种机制是散列的一种变体,用于指示表达式可能依赖的符号未更改,因此该表达式未更改。在这里可能会发生碰撞,因此需要做更多的工作。
在糟糕的情况下,Mathematica 内核可能需要遍历整个表达式以确定它没有改变。这种步行可能与重新评估一样昂贵。版本 7 的新优化(如上所述)是为某些类型的表达式明确记录它所依赖的那些符号。然后可以通过简单地检查自上次评估表达式以来这些符号都没有更改来缩短重新评估检查。
实现细节有点复杂(也有点专有,虽然可能不那么难猜测)。但简而言之,这就是幕后发生的事情。早期版本有时会进行重要的表达式遍历,只是为了发现表达式不需要重新评估。这仍然可能发生,但现在这是一个更加罕见的事件。
---结束编辑---
丹尼尔·利希布劳
Wolfram 研究
关于wolfram-mathematica - Mathematica 执行时错误 : symbol names,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5402214/