1 people like it.

Bigint range sequence

An F# bigint range is slow (see SOQ: http://stackoverflow.com/q/20534191). This an IENum built specifically for bigint that has reasonable speed. ~4 seconds instead of nearly 20 on my old mac mini

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
open System
open System.Collections
open System.Collections.Generic

type bigintRangeEnumerator(start: bigint, max: bigint) =
    let mutable current = bigint.Zero
    let mutable started = false
    interface IEnumerator<bigint> with
        member this.Current = current
        member this.Dispose() = ()

    interface IEnumerator with
        member this.Current = box(current)
        member this.MoveNext() = 
            if ( started = false ) then
                started <- true
                current <- start
                true
            else if ( bigint.op_LessThan(current,max) ) then
                current <- bigint.op_Increment(current)
                true
            else
                false
        member x.Reset() = ()
             
type bigintRange(start: bigint, max: bigint) =
    interface IEnumerable<bigint> with 
        member this.GetEnumerator() = new bigintRangeEnumerator(start, max) :> IEnumerator<bigint>
    interface IEnumerable with
        member this.GetEnumerator() = new bigintRangeEnumerator(start, max) :> IEnumerator
        
let bigint_range s e = new bigintRange(s,e)

let rangeEnd=(bigint (Int32.MaxValue / 100))

#time "on"
bigint_range 1I rangeEnd |> Seq.sum |> printfn "bigint_range range: %A" 
#time "on"
{ 1I.. rangeEnd } |> Seq.sum |> printfn "F# bigint range: %A" 
#time "off"
namespace System
namespace System.Collections
namespace System.Collections.Generic
Multiple items
type bigintRangeEnumerator =
  interface IEnumerator
  interface IEnumerator<bigint>
  new : start:bigint * max:bigint -> bigintRangeEnumerator

Full name: Script.bigintRangeEnumerator

--------------------
new : start:bigint * max:bigint -> bigintRangeEnumerator
val start : bigint
type bigint = Numerics.BigInteger

Full name: Microsoft.FSharp.Core.bigint
val max : bigint
val mutable current : Numerics.BigInteger
property Numerics.BigInteger.Zero: Numerics.BigInteger
val mutable started : bool
Multiple items
type IEnumerator =
  member Current : obj
  member MoveNext : unit -> bool
  member Reset : unit -> unit

Full name: System.Collections.IEnumerator

--------------------
type IEnumerator<'T> =
  member Current : 'T

Full name: System.Collections.Generic.IEnumerator<_>
val this : bigintRangeEnumerator
override bigintRangeEnumerator.Current : bigint

Full name: Script.bigintRangeEnumerator.Current
override bigintRangeEnumerator.Dispose : unit -> unit

Full name: Script.bigintRangeEnumerator.Dispose
override bigintRangeEnumerator.Current : obj

Full name: Script.bigintRangeEnumerator.Current
val box : value:'T -> obj

Full name: Microsoft.FSharp.Core.Operators.box
override bigintRangeEnumerator.MoveNext : unit -> bool

Full name: Script.bigintRangeEnumerator.MoveNext
Numerics.BigInteger.op_LessThan(left: uint64, right: Numerics.BigInteger) : bool
Numerics.BigInteger.op_LessThan(left: Numerics.BigInteger, right: uint64) : bool
Numerics.BigInteger.op_LessThan(left: int64, right: Numerics.BigInteger) : bool
Numerics.BigInteger.op_LessThan(left: Numerics.BigInteger, right: int64) : bool
Numerics.BigInteger.op_LessThan(left: Numerics.BigInteger, right: Numerics.BigInteger) : bool
Numerics.BigInteger.op_Increment(value: Numerics.BigInteger) : Numerics.BigInteger
val x : bigintRangeEnumerator
override bigintRangeEnumerator.Reset : unit -> unit

Full name: Script.bigintRangeEnumerator.Reset
Multiple items
type bigintRange =
  interface IEnumerable
  interface IEnumerable<bigint>
  new : start:bigint * max:bigint -> bigintRange

Full name: Script.bigintRange

--------------------
new : start:bigint * max:bigint -> bigintRange
Multiple items
type IEnumerable =
  member GetEnumerator : unit -> IEnumerator

Full name: System.Collections.IEnumerable

--------------------
type IEnumerable<'T> =
  member GetEnumerator : unit -> IEnumerator<'T>

Full name: System.Collections.Generic.IEnumerable<_>
val this : bigintRange
override bigintRange.GetEnumerator : unit -> IEnumerator<bigint>

Full name: Script.bigintRange.GetEnumerator
override bigintRange.GetEnumerator : unit -> IEnumerator

Full name: Script.bigintRange.GetEnumerator
val bigint_range : s:bigint -> e:bigint -> bigintRange

Full name: Script.bigint_range
val s : bigint
val e : bigint
val rangeEnd : Numerics.BigInteger

Full name: Script.rangeEnd
type Int32 =
  struct
    member CompareTo : value:obj -> int + 1 overload
    member Equals : obj:obj -> bool + 1 overload
    member GetHashCode : unit -> int
    member GetTypeCode : unit -> TypeCode
    member ToString : unit -> string + 3 overloads
    static val MaxValue : int
    static val MinValue : int
    static member Parse : s:string -> int + 3 overloads
    static member TryParse : s:string * result:int -> bool + 1 overload
  end

Full name: System.Int32
field int.MaxValue = 2147483647
module Seq

from Microsoft.FSharp.Collections
val sum : source:seq<'T> -> 'T (requires member ( + ) and member get_Zero)

Full name: Microsoft.FSharp.Collections.Seq.sum
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
Raw view Test code New version

More information

Link:http://fssnip.net/mE
Posted:9 years ago
Author:Tony Lee
Tags: bigint sequence