1 people like it.

List-consing String Builder

See http://stackoverflow.com/questions/18595597/is-using-a-stringbuilder-a-right-thing-to-do-in-f

 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: 
41: 
type SB = System.Text.StringBuilder

let add10M zero add =
    let mutable state = zero
    for i = 1 to 10000000 do
        state <- add state "a"
    state

let testAddBuild reset add build =
    let zero = reset ()
    let t0 = System.DateTime.Now
    let state = add10M zero add
    let t1 = System.DateTime.Now
    build state
    let t2 = System.DateTime.Now
    (t1 - t0).TotalMilliseconds, (t2 - t1).TotalMilliseconds

let sbReset, sbAdd, sbBuild =
    let reset () = SB()
    let add (sb : SB) (s : string) = sb.Append s
    let build sb = sb.ToString() |> ignore
    reset, add, build

let rsReset, rsAdd, rsBuild =
    let reset () = []
    let add t h = h :: t
    let build l = System.String.Join("", List.rev) |> ignore
    reset, add, build

let sbTest () = testAddBuild sbReset sbAdd sbBuild
let rsTest () = testAddBuild rsReset rsAdd rsBuild

let results () =
    let mean test =
        let pairs = [ for i in 1 .. 100 -> printfn "%d" i; test() ]
        (pairs |> List.map fst |> List.sum) / 100.,
        (pairs |> List.map snd |> List.sum) / 100.
    let sbMean = mean sbTest
    let rsMean = mean rsTest
    printfn "SB: %f / %f" (fst sbMean) (snd sbMean)
    printfn "RS: %f / %f" (fst rsMean) (snd rsMean)
namespace System
namespace System.Text
Multiple items
type StringBuilder =
  new : unit -> StringBuilder + 5 overloads
  member Append : value:string -> StringBuilder + 18 overloads
  member AppendFormat : format:string * arg0:obj -> StringBuilder + 4 overloads
  member AppendLine : unit -> StringBuilder + 1 overload
  member Capacity : int with get, set
  member Chars : int -> char with get, set
  member Clear : unit -> StringBuilder
  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
  member EnsureCapacity : capacity:int -> int
  member Equals : sb:StringBuilder -> bool
  ...

Full name: System.Text.StringBuilder

--------------------
System.Text.StringBuilder() : unit
System.Text.StringBuilder(capacity: int) : unit
System.Text.StringBuilder(value: string) : unit
System.Text.StringBuilder(value: string, capacity: int) : unit
System.Text.StringBuilder(capacity: int, maxCapacity: int) : unit
System.Text.StringBuilder(value: string, startIndex: int, length: int, capacity: int) : unit
val add10M : zero:'a -> add:('a -> string -> 'a) -> 'a

Full name: Script.add10M
val zero : 'a
val add : ('a -> string -> 'a)
val mutable state : 'a
val i : int
val testAddBuild : reset:(unit -> 'a) -> add:('a -> string -> 'a) -> build:('a -> unit) -> float * float

Full name: Script.testAddBuild
val reset : (unit -> 'a)
val build : ('a -> unit)
val t0 : System.DateTime
Multiple items
type DateTime =
  struct
    new : ticks:int64 -> DateTime + 10 overloads
    member Add : value:TimeSpan -> DateTime
    member AddDays : value:float -> DateTime
    member AddHours : value:float -> DateTime
    member AddMilliseconds : value:float -> DateTime
    member AddMinutes : value:float -> DateTime
    member AddMonths : months:int -> DateTime
    member AddSeconds : value:float -> DateTime
    member AddTicks : value:int64 -> DateTime
    member AddYears : value:int -> DateTime
    ...
  end

Full name: System.DateTime

--------------------
System.DateTime()
   (+0 other overloads)
System.DateTime(ticks: int64) : unit
   (+0 other overloads)
System.DateTime(ticks: int64, kind: System.DateTimeKind) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, calendar: System.Globalization.Calendar) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: System.DateTimeKind) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: System.Globalization.Calendar) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: System.DateTimeKind) : unit
   (+0 other overloads)
property System.DateTime.Now: System.DateTime
val state : 'a
val t1 : System.DateTime
val t2 : System.DateTime
val sbReset : (unit -> System.Text.StringBuilder)

Full name: Script.sbReset
val sbAdd : (SB -> string -> System.Text.StringBuilder)

Full name: Script.sbAdd
val sbBuild : ('a -> unit)

Full name: Script.sbBuild
val reset : (unit -> System.Text.StringBuilder)
type SB = System.Text.StringBuilder

Full name: Script.SB
val add : (SB -> string -> System.Text.StringBuilder)
val sb : SB
val s : string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
System.Text.StringBuilder.Append(value: char []) : System.Text.StringBuilder
   (+0 other overloads)
System.Text.StringBuilder.Append(value: obj) : System.Text.StringBuilder
   (+0 other overloads)
System.Text.StringBuilder.Append(value: uint64) : System.Text.StringBuilder
   (+0 other overloads)
System.Text.StringBuilder.Append(value: uint32) : System.Text.StringBuilder
   (+0 other overloads)
System.Text.StringBuilder.Append(value: uint16) : System.Text.StringBuilder
   (+0 other overloads)
System.Text.StringBuilder.Append(value: decimal) : System.Text.StringBuilder
   (+0 other overloads)
System.Text.StringBuilder.Append(value: float) : System.Text.StringBuilder
   (+0 other overloads)
System.Text.StringBuilder.Append(value: float32) : System.Text.StringBuilder
   (+0 other overloads)
System.Text.StringBuilder.Append(value: int64) : System.Text.StringBuilder
   (+0 other overloads)
System.Text.StringBuilder.Append(value: int) : System.Text.StringBuilder
   (+0 other overloads)
val build : ('b -> unit)
val sb : 'b
System.Object.ToString() : string
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
val rsReset : (unit -> 'a list)

Full name: Script.rsReset
val rsAdd : ('b list -> 'b -> 'b list)

Full name: Script.rsAdd
val rsBuild : ('c -> unit)

Full name: Script.rsBuild
val reset : (unit -> 'd list)
val add : ('d list -> 'd -> 'd list)
val t : 'd list
val h : 'd
val build : ('d -> unit)
val l : 'd
Multiple items
type String =
  new : value:char -> string + 7 overloads
  member Chars : int -> char
  member Clone : unit -> obj
  member CompareTo : value:obj -> int + 1 overload
  member Contains : value:string -> bool
  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
  member EndsWith : value:string -> bool + 2 overloads
  member Equals : obj:obj -> bool + 2 overloads
  member GetEnumerator : unit -> CharEnumerator
  member GetHashCode : unit -> int
  ...

Full name: System.String

--------------------
System.String(value: nativeptr<char>) : unit
System.String(value: nativeptr<sbyte>) : unit
System.String(value: char []) : unit
System.String(c: char, count: int) : unit
System.String(value: nativeptr<char>, startIndex: int, length: int) : unit
System.String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
System.String(value: char [], startIndex: int, length: int) : unit
System.String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: System.Text.Encoding) : unit
System.String.Join(separator: string, values: System.Collections.Generic.IEnumerable<string>) : string
System.String.Join<'T>(separator: string, values: System.Collections.Generic.IEnumerable<'T>) : string
System.String.Join(separator: string, [<System.ParamArray>] values: obj []) : string
System.String.Join(separator: string, [<System.ParamArray>] value: string []) : string
System.String.Join(separator: string, value: string [], startIndex: int, count: int) : string
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val rev : list:'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.rev
val sbTest : unit -> float * float

Full name: Script.sbTest
val rsTest : unit -> float * float

Full name: Script.rsTest
val results : unit -> unit

Full name: Script.results
val mean : ((unit -> float * float) -> float * float)
val test : (unit -> float * float)
val pairs : (float * float) list
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val map : mapping:('T -> 'U) -> list:'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.map
val fst : tuple:('T1 * 'T2) -> 'T1

Full name: Microsoft.FSharp.Core.Operators.fst
val sum : list:'T list -> 'T (requires member ( + ) and member get_Zero)

Full name: Microsoft.FSharp.Collections.List.sum
val snd : tuple:('T1 * 'T2) -> 'T2

Full name: Microsoft.FSharp.Core.Operators.snd
val sbMean : float * float
val rsMean : float * float
Raw view Test code New version

More information

Link:http://fssnip.net/jM
Posted:10 years ago
Author:Ramon Snir
Tags: string , stringbuilder , list