Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@isaksky
Created August 23, 2016 22: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 isaksky/56eaae5e232d7f13c26dc23650840f90 to your computer and use it in GitHub Desktop.
Save isaksky/56eaae5e232d7f13c26dc23650840f90 to your computer and use it in GitHub Desktop.
Benchmark various ways to read N rows async
open Hopac
open BenchmarkDotNet
open BenchmarkDotNet.Attributes
open BenchmarkDotNet.Running
open System
open System.Data
open System.Data.SqlClient
open System.Threading.Tasks
open BenchmarkDotNet.Configs
open BenchmarkDotNet.Diagnostics.Windows
open Hopac.Infixes
open System
open System.Diagnostics
open System.Threading
open Hopac
open Hopac.Infixes
open Hopac.Extensions
type MyBench() =
[<Benchmark(Baseline=true)>]
member self.SyncLookup () =
use conn = getConn()
use cmd = conn.CreateCommand()
cmd.CommandText <- self.GetCommandText()
use rdr = cmd.ExecuteReader()
let ary = Array.zeroCreate (rdr.FieldCount)
let mutable i = 0
while rdr.Read() do
i <- i + 1
i
[<Benchmark>]
member self.AsyncLookup () =
async {
use conn = new SqlConnection(connStr)
do! conn.OpenAsync() |> Async.AwaitTaskVoid
use cmd = conn.CreateCommand()
cmd.CommandText <- self.GetCommandText()
use! rdr = cmd.ExecuteReaderAsync() |> Async.AwaitTask
let mutable finished = false
while not finished do
let! didRead = rdr.ReadAsync() |> Async.AwaitTask
if not didRead then finished <- true
return ()
} |> Async.RunSynchronously
[<Benchmark>]
member self.HopacLookup () =
job {
use conn = new SqlConnection(connStr)
do! conn.OpenAsync() |> Job.awaitUnitTask
use cmd = conn.CreateCommand()
cmd.CommandText <- self.GetCommandText()
use! rdr = cmd.ExecuteReaderAsync() |> Job.awaitTask
let mutable finished = false
while not finished do
let! didRead = rdr.ReadAsync() |> Job.awaitTask
if not didRead then finished <- true
} |> run
[<Benchmark>]
member self.TaskCE () =
let rec readLoop (rdr:System.Data.SqlClient.SqlDataReader) =
FSharpx.Task.task {
let! didRead = rdr.ReadAsync()
if didRead then
do! readLoop rdr
}
let t = FSharpx.Task.task {
let conn = new SqlConnection(connStr)
let! _ = conn.OpenAsync().ContinueWith(fun t-> 0)
use cmd = conn.CreateCommand()
cmd.CommandText <- self.GetCommandText()
let rdr = cmd.ExecuteReader()
let mutable finished = false
while not finished do
let! didRead = rdr.ReadAsync()
if not didRead then finished <- true
// lmao if you thought you could use "use!"
rdr.Dispose()
cmd.Dispose()
conn.Dispose()
}
let x = t.Result
()
[<Benchmark>]
member self.HopacMB() =
let mb = Mailbox ()
use finished = new ManualResetEventSlim ()
server (Job.forever (mb >>- fun n -> if not n then finished.Set()))
job {
use conn = new SqlConnection(connStr)
do! conn.OpenAsync() |> Job.awaitUnitTask
use cmd = conn.CreateCommand()
cmd.CommandText <- self.GetCommandText()
use! rdr = cmd.ExecuteReaderAsync() |> Job.awaitTask
let mutable finished = false
while not finished do
let! didRead = rdr.ReadAsync() |> Job.awaitTask
do! Mailbox.send mb didRead
if not didRead then finished <- true
} |> start
finished.Wait()
[<Benchmark>]
member self.HopacCH() =
let ch = Ch()
use finished = new ManualResetEventSlim ()
server (Job.forever (ch >>- fun n -> if not n then finished.Set()))
job {
use conn = new SqlConnection(connStr)
do! conn.OpenAsync() |> Job.awaitUnitTask
use cmd = conn.CreateCommand()
cmd.CommandText <- self.GetCommandText()
use! rdr = cmd.ExecuteReaderAsync() |> Job.awaitTask
let mutable finished = false
while not finished do
let! didRead = rdr.ReadAsync() |> Job.awaitTask
do! ch *<- didRead
if not didRead then finished <- true
} |> start
finished.Wait()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment