13

Mathematica には、少なくともバージョン 5.1 から何年もの間、バージョン 7 まで続く奇妙なバグがあります。


Module[{f, L}, L = f[];
  Do[L = f[L, i], {i, 10^4}]] // Timing
  {0.015、ヌル}
Module[{weirdness, L}, L = weirdness[];
  Do[L = weirdness[L, i], {i, 10^4}]] // Timing
  {2.266、ヌル}

  • これは何が原因ですか?ハッシュの問題ですか?

  • バージョン 8 では修正されていますか?

  • テスト以外に、どのシンボル名がスローダウンを引き起こすかを知る方法はありますか?

4

2 に答える 2

19

これは何が原因ですか?ハッシュの問題ですか?

はい、多かれ少なかれ。

バージョン 8 では修正されていますか?

はい(多かれ少なかれ)。つまり、「完全な」意味で修正することはできません。しかし、最も一般的なケースは、はるかに適切に処理されます。

テスト以外に、どのシンボル名がスローダウンを引き起こすかを知る方法はありますか?

私が知っている方法はありません。

バージョン 7 には、バージョン 8 のものと同様の性質の以前の修正があります。デフォルトではオフになっていました (出荷時にテストする十分な時間がなかったため、バージョン 7.0 ではオンになりませんでした。 1)。以下の方法でアクセスできます。

SetSystemOptions["NeedNotReevaluateOptions"->{"UseSymbolLists"->True}];

これにより、例が合理的な領域に戻ります。

Module[{weirdness, L}, L = weirdness[];
  Do[L = weirdness[L, i], {i, 10^4}]] // Timing

Out[8]= {0.020997, Null}

- -編集 - -

ここに含まれる最適化について、もう少し詳しく説明できます。最初に Mathematica が「無限評価」をエミュレートすることを思い出してください.つまり,式は変化しなくなるまで評価を続けます.これにはコストがかかる可能性があるため、可能な場合はそれを未然に防ぐために慎重に短絡を最適化する必要があります。

私たちが使用するメカニズムはハッシュの変形であり、式が依存する可能性のあるシンボルが変更されていないため、式が変更されていないことを示すのに役立ちます。ここで衝突が発生する可能性があるため、より多くの作業が必要になります。

悪いケースでは、Mathematica カーネルは、式が変更されていないことを確認するために、式全体をたどる必要があるかもしれません。このウォークは、再評価と同じくらいコストがかかる可能性があります。バージョン 7 (上記) の新しい最適化は、式のいくつかのタイプについて、依存するシンボルを明示的に記録することです。次に、式が最後に評価されてからこれらのシンボルが変更されていないことを確認するだけで、再評価チェックを短縮できます。

実装の詳細は少し複雑です (推測するのはそれほど難しくありませんが、少し独自仕様もあります)。しかし、簡単に言えば、それはボンネットの下で起こっていることです。以前のバージョンでは、式が再評価を必要としないことを発見するためだけに、かなりの式トラバーサルを行うことがありました。これはまだ発生する可能性がありますが、現在でははるかにまれなイベントです.

---編集終了---

Daniel Lichtblau Wolfram Research

于 2011-03-23T16:19:41.370 に答える
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}];

ここに画像の説明を入力

于 2011-03-23T10:35:33.027 に答える