Skip to content

Commit

Permalink
Adding docu and performance test for PersistentVector - references #2
Browse files Browse the repository at this point in the history
  • Loading branch information
forki committed Dec 10, 2013
1 parent 5c4e47d commit f0ec267
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 2 deletions.
1 change: 1 addition & 0 deletions FSharpx.Collections.sln
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{560133F0-6
ProjectSection(SolutionItems) = preProject
help\index.md = help\index.md
help\PersistentHashMap.fsx = help\PersistentHashMap.fsx
help\PersistentVector.fsx = help\PersistentVector.fsx
EndProjectSection
EndProject
Global
Expand Down
4 changes: 2 additions & 2 deletions help/PersistentHashMap.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ PersistentHashMaps are immutable and therefor allow to create new version withou
let m' =
m
|> add 104 "!"
|> add 42 "hi" // replace existing
|> add 42 "hi" // replace existing value

find 42 m'
// [fsi:val it : string = "hi"]
Expand All @@ -51,7 +51,7 @@ find 42 m
let stringBasedMap = ofSeq [("a",1); ("b",2); ("c",3); ("d",4); ("e",5)]
// [fsi:val stringBaseMap : FSharpx.Collections.PersistentHashMap<string,int>]

// Sequare all values in a map
// Square all values in a map
let stringBasedMap' = map (fun x -> x * x) stringBasedMap
stringBasedMap'.["d"]
// [fsi:val it : int = 16]
Expand Down
114 changes: 114 additions & 0 deletions help/PersistentVector.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
(*** hide ***)
#r "../build/FSharpx.Collections.dll"
open System


(**
PersistentVector
=============
A Vector is a collection of values indexed by contiguous integers. Vectors support access to items by index in log32N hops. count is O(1). conj puts the item at the end of the vector.
*)

open FSharpx.Collections.PersistentVector


(**
Performance tests
-----------------
Bulk operations on HashMaps use an internal TransientHashMap in order to get much better performance. The following scripts shows this.
*)

let c = 5
let r = new System.Random()

open FSharpx.Collections.TimeMeasurement

let initArrayAndVectorFromList n =
sprintf "Init with n = %d" n |> printInFsiTags
let list = [for i in 1..n -> r.Next()]

let initvector list =
let v = ref empty
for x in list do
v := conj x !v
!v

compareThreeRuntimes c
" Array.ofSeq" (fun () -> Array.ofSeq list)
" Multiple PersistentVector.conj " (fun () -> initvector list)
" PersistentVector.ofSeq" (fun () -> ofSeq list)

let lookupInArrayAndVector n count =
sprintf "%d Lookups in size n = %d" count n |> printInFsiTags
let list = [for i in 1..n -> r.Next()]
let array = Array.ofSeq list
let vector = ofSeq list

compareTwoRuntimes c
" Array" (fun () -> for i in 1..count do array.[r.Next n] |> ignore)
" PersistentVector" (fun () -> for i in 1..count do nth (r.Next n) vector |> ignore)


let replaceInArrayAndVector n count =
sprintf "%d writes in size n = %d" count n |> printInFsiTags
let list = [for i in 1..n -> r.Next()]
let array = Array.ofSeq list
let vector = ofSeq list

compareTwoRuntimes c
" Array" (fun () -> for i in 1..count do array.[r.Next n] <- r.Next())
" PersistentVector" (fun () -> for i in 1..count do update (r.Next n) (r.Next()) vector |> ignore)

initArrayAndVectorFromList 10000
initArrayAndVectorFromList 100000
initArrayAndVectorFromList 1000000

lookupInArrayAndVector 10000 10000
lookupInArrayAndVector 100000 10000
lookupInArrayAndVector 1000000 10000
lookupInArrayAndVector 10000000 10000

replaceInArrayAndVector 10000 10000
replaceInArrayAndVector 100000 10000
replaceInArrayAndVector 1000000 10000
replaceInArrayAndVector 10000000 10000

// [fsi:Init with n = 10000]
// [fsi: Array.ofSeq 0.0ms]
// [fsi: Multiple PersistentVector.conj 3.0ms]
// [fsi: PersistentVector.ofSeq 3.0ms]
// [fsi:Init with n = 100000]
// [fsi: Array.ofSeq 0.4ms]
// [fsi: Multiple PersistentVector.conj 38.8ms]
// [fsi: PersistentVector.ofSeq 17.6ms]
// [fsi:Init with n = 1000000]
// [fsi: Array.ofSeq 5.4ms]
// [fsi: Multiple PersistentVector.conj 420.6ms]
// [fsi: PersistentVector.ofSeq 250.6ms]
// [fsi:10000 Lookups in size n = 10000]
// [fsi: Array 0.0ms]
// [fsi: PersistentVector 0.4ms]
// [fsi:10000 Lookups in size n = 100000]
// [fsi: Array 0.0ms]
// [fsi: PersistentVector 0.6ms]
// [fsi:10000 Lookups in size n = 1000000]
// [fsi: Array 0.0ms]
// [fsi: PersistentVector 2.0ms]
// [fsi:10000 Lookups in size n = 10000000]
// [fsi: Array 0.0ms]
// [fsi: PersistentVector 3.4ms]
// [fsi:10000 writes in size n = 10000]
// [fsi: Array 0.2ms]
// [fsi: PersistentVector 11.4ms]
// [fsi:10000 writes in size n = 100000]
// [fsi: Array 0.2ms]
// [fsi: PersistentVector 11.2ms]
// [fsi:10000 writes in size n = 1000000]
// [fsi: Array 0.2ms]
// [fsi: PersistentVector 15.0ms]
// [fsi:10000 writes in size n = 10000000]
// [fsi: Array 1.0ms]
// [fsi: PersistentVector 33.8ms]
1 change: 1 addition & 0 deletions help/templates/template-project.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ <h3 class="muted">{project-name}</h3>
<li><a href="https://github.com/forki/FSharpx.Collections/blob/master/LICENSE.md">License (MS-PL)</a></li>
<li><a href="changelog.html">Changelog</a></li>
<li class="nav-header">Articles</li>
<li><a href="PersistentVector.html">PersistentVector</a></li>
<li><a href="PersistentHashMap.html">PersistentHashMap</a></li>
<li class="nav-header">Documentation</li>
<li><a href="apidocs/index.html">API Reference</a></li>
Expand Down
1 change: 1 addition & 0 deletions help/templates/template.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<li><a href="https://github.com/forki/FSharpx.Collections/blob/master/LICENSE.md">License (MS-PL)</a></li>
<li><a href="@Root/changelog.html">Changelog</a></li>
<li class="nav-header">Articles</li>
<li><a href="@Root/PersistentVector.html">PersistentVector</a></li>
<li><a href="@Root/PersistentHashMap.html">PersistentHashMap</a></li>
<li class="divider"></li>

Expand Down
1 change: 1 addition & 0 deletions src/app/FSharpx.Collections/FSharpx.Collections.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<Compile Include="AssemblyInfo.fs" />
<Compile Include="Exceptions.fs" />
<Compile Include="Interfaces.fs" />
<Compile Include="Infrastructure.fs" />
<Compile Include="LazyList.fsi" />
<Compile Include="LazyList.fs" />
<Compile Include="ResizeArray.fsi" />
Expand Down
42 changes: 42 additions & 0 deletions src/app/FSharpx.Collections/Infrastructure.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module FSharpx.Collections.TimeMeasurement

/// Stops the runtime for a given function
let stopTime f =
let sw = new System.Diagnostics.Stopwatch()
sw.Start()
let result = f()
sw.Stop()
result,float sw.ElapsedMilliseconds

/// Stops the average runtime for a given function and applies it the given count
let stopAverageTime count f =
let sw = new System.Diagnostics.Stopwatch()
let list = [1..count]
sw.Start()
let results = List.map (fun _ -> f()) list
sw.Stop()
results,float sw.ElapsedMilliseconds / float count

let printInFsiTags s = printfn " [fsi:%s]" s

/// Stops the average runtime for a given function and applies it the given count
/// Afterwards it reports it with the given description
let stopAndReportAvarageTime count desc f =
let results,time = stopAverageTime count f
sprintf "%s %Ams" desc time |> printInFsiTags
results,time

/// Stops the average runtime for the given functions
/// Afterwards it reports it with the given descriptions
let compareTwoRuntimes count desc1 f1 desc2 f2 =
let _,time1 = stopAndReportAvarageTime count desc1 f1
let _,time2 = stopAndReportAvarageTime count desc2 f2
()

/// Stops the average runtime for the given functions
/// Afterwards it reports it with the given descriptions
let compareThreeRuntimes count desc1 f1 desc2 f2 desc3 f3 =
let _,time1 = stopAndReportAvarageTime count desc1 f1
let _,time2 = stopAndReportAvarageTime count desc2 f2
let _,time3 = stopAndReportAvarageTime count desc3 f3
()

0 comments on commit f0ec267

Please sign in to comment.