Pregunta

I am playing with the F# Interactive Console and comparing the runtime of some numeric operations. On this code the total runtime seems to double only be repeating the declaration of one variable.

In VS 2010 I do:

open System.Diagnostics
let mutable a=1

Then I select this below and run it with Alt+Enter

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

it takes more or less: 320 ms

now i select this and hit 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

almost double: 620 ms

The same block but including the declaration at the top takes almost double. Shouldn't it be the same since I declare the variable before Stopwatch.StartNew() ? Does this have to do with the interactive console? I have the same results using the #time directive.

¿Fue útil?

Solución

I'm not convinced any of the answers yet are quite right. I think a is represented the same in both cases. And by that I mean an individual type is emitted dynamically wrapping that mutable value (certainly on the heap!). It needs to do this since in both cases, a is a top-level binding that can be accessed by subsequent interactions.

So all that said, my theory is this: in the first case, the dynamic type emitted by FSI is loaded at the end of the interaction, in order to output its default value. In the second case, however, the type wrapping a is not loaded until it is first accessed, in the loop, after the StopWatch was started.

Otros consejos

Daniel is right - if you define a variable in a separate FSI interaction, then it is represented differently.

To get a correct comparison, you need to declare the variable as local in both cases. The easiest way to do that is to nest the code under do (which turns everything under do into a local scope) and then evaluate the entire do block at once. See the result of the following two examples:

// 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 

The difference I get when I run them is not measureable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top