Skip to content

Instantly share code, notes, and snippets.

@liboz
Created September 18, 2016 01:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save liboz/c9e529d0292f25135243721157b93fae to your computer and use it in GitHub Desktop.
Save liboz/c9e529d0292f25135243721157b93fae to your computer and use it in GitHub Desktop.
open BenchmarkDotNet.Running
open BenchmarkDotNet.Attributes
open BenchmarkDotNet.Configs
open BenchmarkDotNet.Diagnostics.Windows
open BenchmarkDotNet.Jobs
open System.Collections.Generic
open System.Collections
open System
let inline newSimpleIntegralRange minValue maxValue n step m =
// a constrained, common simple iterator that is fast.
let singleStepRangeEnumerator () =
let value : Ref<'T> = ref (n - LanguagePrimitives.GenericOne)
let inline current () =
// according to IEnumerator<int>.Current documentation, the result of of Current
// is undefined prior to the first call of MoveNext and post called to MoveNext
// that return false (see https://msdn.microsoft.com/en-us/library/58e146b7%28v=vs.110%29.aspx)
// so we should be able to just return value here, which would be faster
let derefValue = !value
if derefValue < n then
failwith "fail"
elif derefValue > m then
failwith "fail"
else
derefValue
{ new IEnumerator<'T> with
member __.Dispose () = ()
member __.Current = current ()
interface IEnumerator with
member __.Current = box (current ())
member __.Reset () = value := n - LanguagePrimitives.GenericOne
member __.MoveNext () =
let derefValue = !value
if derefValue < m then
value := derefValue + LanguagePrimitives.GenericOne
true
elif derefValue = m then
value := derefValue + LanguagePrimitives.GenericOne
false
else false }
{ new IEnumerable<'T> with
member __.GetEnumerator () = singleStepRangeEnumerator ()
interface IEnumerable with
member __.GetEnumerator () = (singleStepRangeEnumerator ()) :> IEnumerator }
let NewRangeInt32 n step m : seq<int> = newSimpleIntegralRange Int32.MinValue Int32.MaxValue n step m
let inline oldSimpleIntegralRange minValue maxValue n step m =
// a constrained, common simple iterator that is fast.
let singleStepRangeEnumerator () =
let value : Ref<'T> = ref (n - LanguagePrimitives.GenericOne)
let inline current () =
// according to IEnumerator<int>.Current documentation, the result of of Current
// is undefined prior to the first call of MoveNext and post called to MoveNext
// that return false (see https://msdn.microsoft.com/en-us/library/58e146b7%28v=vs.110%29.aspx)
// so we should be able to just return value here, which would be faster
if !value < n then
failwith "fail"
elif !value > m then
failwith "fail"
else
!value
{ new IEnumerator<'T> with
member __.Dispose () = ()
member __.Current = current ()
interface IEnumerator with
member __.Current = box (current ())
member __.Reset () = value := n - LanguagePrimitives.GenericOne
member __.MoveNext () =
if !value < m then
value := !value + LanguagePrimitives.GenericOne
true
elif !value = m then
value := m + LanguagePrimitives.GenericOne
false
else false }
{ new IEnumerable<'T> with
member __.GetEnumerator () = singleStepRangeEnumerator ()
interface IEnumerable with
member __.GetEnumerator () = (singleStepRangeEnumerator ()) :> IEnumerator }
let OldRangeInt32 n step m : seq<int> = oldSimpleIntegralRange Int32.MinValue Int32.MaxValue n step m
let lowerBound = -100
let upperBound = lowerBound*(-1)
type Range () =
[<Params(10, 100, 1000, 10000, 1000000)>]
member val public upperBound = 0 with get, set
member val public lowerBound = 0 with get, set
[<Setup>]
member this.SetupData() =
this.lowerBound <- this.upperBound * (-1)
[<Benchmark>]
member this.oldRange () =
OldRangeInt32 this.lowerBound 1 this.upperBound
|> Seq.length
[<Benchmark>]
member this.newRange () =
NewRangeInt32 this.lowerBound 1 this.upperBound
|> Seq.length
let makeJob (jit: Jit) (platform: Platform) =
let job = new Job()
job.Jit <- jit
job.Platform <- platform
job.LaunchCount <- new Count(5)
job.TargetCount <- new Count(50)
job
let [<EntryPoint>] main args =
let config = ManualConfig.Create(DefaultConfig.Instance)
config.Add(new MemoryDiagnoser())
config.Add(makeJob Jit.RyuJit Platform.X64)
config.Add(makeJob Jit.LegacyJit Platform.X86)
BenchmarkRunner.Run<Range>(config) |> ignore
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment