Mathematica执行时错误:符号名称

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)

在此输入图像描述