> Any thoughts on the speed differences?

Your timings are a bit slanted by the construction of the list. Essentially, you're timing the act of creating a list of 1000000 cons cells and <i>then<i> summing them. Most of that time is in the creation. When compared with raw calculation in a loop, recursively pattern matching over a list (as fold_left does) will certainly be slower. It's not really a fair comparison. [:)] > Is there some dark side to using a for loop and a mutable variable? Not really. Mutable state isn't necessarily a bad thing -- especially when it's neatly encapsulated inside a function like you've done. In that case there aren't any side effects. In fact, you'll find lots of code in the F# libraries themselves that are written similarly. However, if you want to write in a more functional style that doesn't use a for-loop with a mutable accumulation variable, you could define the function in terms of recursion. This function should be just as fast: <code lang=fsharp> #time;; let xy n = let rec aux acc i = if i > n then acc else aux (acc + i) (i + 1) printfn("%A") (aux 0 1) xy(100000000);; </code>

By on 1/29/2008 5:51 AM ()

Dustin,

Thanks for the response. I tried out your code and interestingly it was about twice as fast as my "for loop". Then, just for fun I tried adding random numbers rather than the consecutive integers. Oddly, in that case both routines took exactly the same amount of time, 2.109 seconds on my machine.

Thanks again.

Mitchell

By on 1/31/2008 1:56 PM ()

You can replace the list with a sequence. This is a basic collection that only implments IEnumerable, because it only implments IEnumerable - its lazy there's no construction time:

1
2
{ for i in 0..1000000 -> rand.Next() }
|>Seq.fold1 (+);;

Given the following snippets:

1)

1
2
[for i in 0..1000000 -> rand.Next()]
|>List.fold1_left (+);;

2)

1
2
{ for i in 0..1000000 -> rand.Next() }
|>Seq.fold1 (+);;

3)

1
2
3
4
5
6
7
let xy n =
    let ay = ref 0
    for j = 1 to n do
        ay := !ay + rand.Next() 
    done
    printfn("%A") ay    
xy(1000000);;

On my laptop this gives the following timings:

1) 00.934, 00.933, 01.194

2) 00.545, 00.530, 00.499

3) 00.46, 00.41, 00.40

So the sequence still has a little extra overhead, but its only a gnat's whisker off the mutable solution.

By on 1/29/2008 12:52 PM ()

Robert,

Thanks for the suggestion, the information and the experimentation. I'll have to read up on what a sequence is.

Mitchell

By on 1/30/2008 5:00 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper