Last active
August 29, 2015 14:23
-
-
Save buybackoff/e7ceb018e983df1b1573 to your computer and use it in GitHub Desktop.
F# Fast Events
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
namespace Test | |
open System | |
open System.Linq | |
open System.Linq.Expressions | |
//thanks to http://v2matveev.blogspot.ru/2010/06/f-performance-of-events.html | |
// helper type that will perform invocation | |
type internal Invoker<'D, 'A> = delegate of 'D * obj * 'A -> unit | |
module internal EventHelper = | |
let inline invoker<'D, 'A when 'D :> Delegate and 'D : delegate<'A, unit> and 'D : null> = | |
let d = Expression.Parameter(typeof<'D>, "dlg") | |
let sender = Expression.Parameter(typeof<obj>, "sender") | |
let arg = Expression.Parameter(typeof<'A>, "arg") | |
let lambda = Expression.Lambda<Invoker<'D, 'A>>(Expression.Invoke(d, sender, arg), d, sender, arg) | |
lambda.Compile() | |
type internal EventV2<'D, 'A when 'D :> Delegate and 'D : delegate<'A, unit> and 'D : null>() = | |
let mutable multicast : 'D = null | |
// this inline gives 10x better performance for SortedMap Add/Insert operation | |
member inline x.Trigger(args: 'A) = | |
match multicast with | |
| null -> () | |
| d -> EventHelper.invoker.Invoke(d, null, args) // DelegateEvent used: d.DynamicInvoke(args) |> ignore | |
// member x.Publish = | |
// { new IDelegateEvent<'D> with | |
// member x.AddHandler(d) = | |
// multicast <- System.Delegate.Combine(multicast, d) :?> 'D | |
// member x.RemoveHandler(d) = | |
// multicast <- System.Delegate.Remove(multicast, d) :?> 'D } | |
// member x.Publish = | |
// { new IEvent<'D,'A> with | |
// member x.Subscribe(observer: IObserver<'A>): IDisposable = | |
// failwith "Not implemented yet" | |
// member x.AddHandler(d) = | |
// multicast <- System.Delegate.Combine(multicast, d) :?> 'D | |
// member x.RemoveHandler(d) = | |
// multicast <- System.Delegate.Remove(multicast, d) :?> 'D } | |
member x.Publish = | |
{ new IEvent<'A> with | |
member x.Subscribe(observer: IObserver<'A>): IDisposable = | |
failwith "Not implemented yet" | |
member x.AddHandler(d) = | |
multicast <- System.Delegate.Combine(multicast, d) :?> 'D | |
member x.RemoveHandler(d) = | |
multicast <- System.Delegate.Remove(multicast, d) :?> 'D } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment