Skip to content

Instantly share code, notes, and snippets.

@jvrdev
Last active August 29, 2015 14:24
Show Gist options
  • Select an option

  • Save jvrdev/a3d558222e6a8e6ee18d to your computer and use it in GitHub Desktop.

Select an option

Save jvrdev/a3d558222e6a8e6ee18d to your computer and use it in GitHub Desktop.
Testing evaluation strategies for long operations
open System
open System.Threading
open System.Linq
open System.Threading.Tasks
open System.Diagnostics
[<EntryPoint>]
let main argv =
let rand = new Random()
let opCount = 5
let opAvgMillis = 250.0
let getLengthyOperation () =
let waitMillis = [1 .. 12]
|> Seq.averageBy (fun _ -> rand.NextDouble())
|> (*) (opAvgMillis * 2.0)
|> int
fun () -> Thread.Sleep waitMillis; true
let lengthyOperations = [1 .. opCount]
|> Seq.map (fun _ -> getLengthyOperation ())
|> Seq.toArray
let evalStartNew (xs : seq<unit -> bool>) =
let tasks = xs.Select(fun x -> Task.Factory.StartNew(fun () -> x ())).ToArray()
Task.WaitAll (tasks |> Seq.map (fun t -> t :> Task) |> Seq.toArray)
tasks.All (fun t -> t.Result)
let evalAsParallelDef (xs : seq<unit -> bool>) =
xs.AsParallel().All(fun f -> f())
let evalAsParallelForce (n : int) (xs : seq<unit -> bool>) =
xs.AsParallel().WithDegreeOfParallelism(Math.Min(63, (Math.Max(1, n)))).WithExecutionMode(ParallelExecutionMode.ForceParallelism).All(fun f -> f())
let evals = [(evalStartNew, "evalStartNew"); (evalAsParallelDef, "evalAsParallelDef"); (evalAsParallelForce 2, "evalAsParallelForce 2");
(evalAsParallelForce 8, "evalAsParallelForce 8"); (evalAsParallelForce 64, "evalAsParallelForce 64")]
for (eval, name) in evals do
let watch = Stopwatch.StartNew ()
let result = eval lengthyOperations
watch.Stop ()
printfn "%s took %A; speedup was x%.3f" name watch.Elapsed (opAvgMillis * (double)opCount / watch.Elapsed.TotalMilliseconds)
System.Console.ReadLine () |> ignore
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment