-
-
Save slang25/ea89d25d3905f0047c9cf7b35b0bd99a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Learn more about F# at http://fsharp.org | |
open System | |
open System.Text | |
open System.Collections.Generic | |
open System.Linq | |
open BenchmarkDotNet.Attributes | |
open BenchmarkDotNet.Running | |
module Strings = | |
let private chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" | |
let getNewString (rnd: Random) = | |
let len = rnd.Next() % 25 | |
let chars = Enumerable.Repeat(chars, len).Select(fun s -> s.[rnd.Next(s.Length)]).ToArray() | |
String(chars) | |
[<AutoOpenAttribute>] | |
module StringBuffer = | |
type StringBuffer = StringBuilder -> unit | |
type StringBufferBuilder () = | |
member inline __.Yield (txt: string) = fun (b: StringBuilder) -> b.Append txt |> ignore | |
member inline __.Yield (c: char) = fun (b: StringBuilder) -> b.Append c |> ignore | |
member inline __.Yield (strings: #seq<string>) = | |
fun (b: StringBuilder) -> for s in strings do s |> b.AppendLine |> ignore | |
member inline __.YieldFrom (f: StringBuffer) = f | |
member __.Combine (f, g) = fun (b: StringBuilder) -> f b; g b | |
member __.Delay f = fun (b: StringBuilder) -> (f()) b | |
member __.Zero () = ignore | |
member __.For (xs: 'a seq, f: 'a -> StringBuffer) = | |
fun (b: StringBuilder) -> | |
let e = xs.GetEnumerator () | |
while e.MoveNext() do | |
(f e.Current) b | |
member __.While (p: unit -> bool, f: StringBuffer) = | |
fun (b: StringBuilder) -> while p () do f b | |
member __.Run (f: StringBuffer) = | |
let b = StringBuilder() | |
do f b | |
b.ToString() | |
let stringBuffer = new StringBufferBuilder () | |
[<MemoryDiagnoser>] | |
type Bench() = | |
let rnd = new Random() | |
let times = 1_0_000 | |
let inputs = Array.init times (fun _ -> Strings.getNewString rnd) | |
[<Benchmark(Baseline=true)>] | |
member __.Concats() = | |
let mutable acc = String.Empty | |
for i in 0 .. times-1 do | |
acc <- acc + inputs.[i] | |
[<Benchmark>] | |
member __.StringBuilder() = | |
let sb = StringBuilder() | |
for i in 0 .. times-1 do | |
inputs.[i] | |
|> sb.Append | |
|> ignore | |
[<BenchmarkAttribute>] | |
member __.CompExpr() = | |
stringBuffer { | |
for i in 0 .. times-1 -> inputs.[i] | |
} |> ignore | |
[<EntryPoint>] | |
let main argv = | |
let summary = BenchmarkRunner.Run<Bench>() | |
printfn "%A" summary | |
0 // return an integer exit code |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment