4

F#Interactive Consoleで遊んでいて、いくつかの数値操作の実行時間を比較しています。このコードでは、合計実行時間は2倍になり、1つの変数の宣言を繰り返すだけのようです。

VS 2010では、次のことを行います。

open System.Diagnostics
let mutable a=1

次に、これを下で選択して、Alt+Enterで実行します

let stopWatch = Stopwatch.StartNew()
for i=1 to 200100100 do
    a <- a + 1
stopWatch.Stop()
printfn "stopWatch.Elapsed: %f" stopWatch.Elapsed.TotalMilliseconds

多かれ少なかれかかります:320ミリ秒

これを選択してAlt+Enterキーを押します。

let mutable a=1
let stopWatch = Stopwatch.StartNew()
for i=1 to 200100100 do
    a <- a + 1
stopWatch.Stop()
printfn "stopWatch.Elapsed: %f" stopWatch.Elapsed.TotalMilliseconds

ほぼ2倍:620ミリ秒

同じブロックですが、上部に宣言を含めると、ほぼ2倍になります。Stopwatch.StartNew()の前に変数を宣言しているので、同じではないでしょうか?これはインタラクティブコンソールと関係がありますか?#timeディレクティブを使用しても同じ結果が得られます。

4

2 に答える 2

4

私は答えのどれもまだ完全に正しいとは確信していません。aどちらの場合も同じように表現されていると思います。つまり、個々のタイプは、その可変値を動的にラップして放出されることを意味します(確かにヒープ上にあります!)。aどちらの場合も、後続のインタラクションからアクセスできる最上位のバインディングであるため、これを行う必要があります。

つまり、私の理論は次のとおりです。最初のケースでは、デフォルト値を出力するために、FSIによって発行された動的タイプがインタラクションの最後にロードされます。ただし、2番目のケースでは、タイプラッピングaは、開始後、ループ内で最初にアクセスされるまでロードされませんStopWatch

于 2012-07-20T21:30:44.600 に答える
3

ダニエルは正しいです-別のFSIインタラクションで変数を定義すると、それは異なって表現されます。

正しい比較を行うには、どちらの場合も変数をローカルとして宣言する必要があります。これを行う最も簡単な方法は、コードを下にネストしてdo(すべてをdoローカルスコープに変換します)、doブロック全体を一度に評価することです。次の2つの例の結果を参照してください。

// A version with variable declaration excluded
do
  let mutable a=1 
  let stopWatch = Stopwatch.StartNew() 
  for i=1 to 200100100 do 
    a <- a + 1 
  stopWatch.Stop() 
  printfn "stopWatch.Elapsed: %f" stopWatch.Elapsed.TotalMilliseconds 

// A version with variable declaration included
do
  let stopWatch = Stopwatch.StartNew() 
  let mutable a=1 
  for i=1 to 200100100 do 
    a <- a + 1 
  stopWatch.Stop() 
  printfn "stopWatch.Elapsed: %f" stopWatch.Elapsed.TotalMilliseconds 

それらを実行したときに得られる違いは測定できません。

于 2012-07-20T21:18:45.363 に答える