Mr.*_*ard 13 wolfram-mathematica timing execution-time
Mathematica中存在一个奇怪的错误,至少从版本5.1开始,并持续到版本7.
Module[{f, L}, L = f[];
Do[L = f[L, i], {i, 10^4}]] // Timing
Run Code Online (Sandbox Code Playgroud)
{0.015, Null}
Module[{weirdness, L}, L = weirdness[];
Do[L = weirdness[L, i], {i, 10^4}]] // Timing
Run Code Online (Sandbox Code Playgroud)
{2.266, Null}
是什么导致这个?这是一个哈希问题吗?
在版本8中修复了吗?
除了测试之外,有没有办法知道哪些符号名称导致减速?
Dan*_*lau 19
是什么导致这个?这是一个哈希问题吗?
是的,或多或少.
在版本8中修复了吗?
是(也或多或少).也就是说,不可能以任何"完整"的意义来修复.但是最常见的情况要好得多.
除了测试之外,有没有办法知道哪些符号名称导致减速?
我没有意识到这一点.
在版本7中,有一个类似性质的早期修复版本与版本8中的版本相似.它默认是关闭的(我们没有足够的时间来测试它,当我们发货时,它没有在7.0版本上打开. 1).可以按如下方式访问它.
SetSystemOptions["NeedNotReevaluateOptions"->{"UseSymbolLists"->True}];
Run Code Online (Sandbox Code Playgroud)
这使你的榜样回到了合理的境界.
Module[{weirdness, L}, L = weirdness[];
Do[L = weirdness[L, i], {i, 10^4}]] // Timing
Run Code Online (Sandbox Code Playgroud)
Out [8] = {0.020997,Null}
- -编辑 - -
我可以稍微详细地解释一下这里涉及的优化.首先回想一下,Mathematica模仿"无限评估",即表达式不断进行评估,直到它们不再发生变化.这可能是昂贵的,因此需要仔细的短路优化以在可能的情况下阻止它.
我们使用的机制是散列的变体,用于指示表达式可能依赖的符号不变,因此该表达式不变.在这里可能发生碰撞,因此需要更多的工作.
在一个不好的情况下,Mathematica内核可能需要遍历整个表达式以确定它是否未更改.这种行走可能与重新评估一样昂贵.对版本7(上面提到的)新的优化是针对某些类型的表达式明确地记录它所依赖的那些符号.然后,通过简单地检查自上次评估表达式以来没有更改这些符号,可以缩短重新评估检查.
实现细节有点涉及(也有点专有,但可能不是很难猜测).但简而言之,这就是幕后发生的事情.早期版本有时会进行重要的表达式遍历,只是为了发现表达式不需要重新评估.这仍然可能发生,但现在这是一个更罕见的事件.
---结束编辑---
Daniel Lichtblau Wolfram Research
Sjo*_*ies 10
至于版本8:我尝试了100,000个不同长度的随机字符串,并没有发现任何异常.
chars = StringCases[CharacterRange["A", "z"], WordCharacter] //Flatten;
res = Table[
ToExpression[
StringReplace[
"First[AbsoluteTiming[Module[{weirdness,L},L=weirdness[];\
\[IndentingNewLine]Do[L=weirdness[L,i],{i,10^4}]]]]",
"weirdness" ->
StringJoin[
RandomChoice[chars, RandomInteger[{1, 20}]]]]], {100000}];
Run Code Online (Sandbox Code Playgroud)