Skip to main content
3 of 3
added 1 character in body; edited title
Jamal
  • 34.9k
  • 13
  • 133
  • 237

Compare performance of simple addition on one to many cores

I read recently that ENIAC originally was capable of 5000 additions per second. Naturally, I had to test my own laptop's capabilities and this became an instructive experiment in F#, which I suck at.

So, I am looking for feedback in two areas:

  • What is the most concise way to write this in F#, or at least most closely aligned with the functional paradigm?

  • Did I miss something for performance? Can this be done in a much more performant fashion?

module Program

open System
open System.Diagnostics

[<AutoOpen>]
module timingStuff = 
    let pickRunmode() = 
        Console.WriteLine("choose number of processes to spawn (default 1)")
        Console.ReadLine()

    let feedback (input : string) = 
        Console.WriteLine("you picked {0}", input)
        Console.WriteLine("now running")

    let quitOrContinue() = 
        Console.WriteLine("q to quit else continue with keypress")
        Console.ReadKey().KeyChar <> 'q'

    let rec addOne x stop = 
        let r = x + 1
        if stop() then r
        else addOne r stop

    let finished stopticks = (fun _ -> Stopwatch.GetTimestamp() >= stopticks)
    let secondsToTicks x = x * 1000L * 10000L
    let prettyNumbers (x : int) = String.Format("{0:#,0}", x)

    let printResult result start = 
        let final = (Stopwatch.GetTimestamp() - start |> TimeSpan).TotalSeconds
        let pretty = prettyNumbers result
        sprintf "performed %s operations in %f seconds" pretty final |> Console.WriteLine

    let op duration start = 
        duration
        |> secondsToTicks
        |> (+) start
        |> finished
        |> addOne 0

    let opAsync duration start procs = 
        [ for i in [ 1..procs ] -> async { return op duration start } ]
        |> Async.Parallel
        |> Async.RunSynchronously

[<EntryPoint>]
let main argv = 
    let loop() = 
        let input = 
            match Int32.TryParse(pickRunmode()) with
            | true, i -> i
            | _ -> 1
        input
        |> string
        |> feedback
        |> ignore
        let start = Stopwatch.GetTimestamp()
        let result = opAsync 1L start input |> Seq.sum
        printResult result start |> ignore
        quitOrContinue()
    while loop() do
        ()
    0