WeakEvent icon indicating copy to clipboard operation
WeakEvent copied to clipboard

Ideas for better performance and safety

Open mlaily opened this issue 3 years ago • 2 comments

Hello :)

I imagine you did some research before starting this project, and I guess you probably wouldn't have started the project if there were already a satisfying implementation available. I know it was a long time ago, but do you remember if you had the chance to review this: https://www.codeproject.com/Articles/29922/Weak-Events-in-C ?

The author seems trustworthy ("lead developer on SharpDevelop"), and the performance of his implementation is pretty much excellent. To achieve such performance he replaces reflection with System.Reflection.Emit.DynamicMethod and IL code.

  • Is there any particular reason you didn't use this technique in your library, when the running platform supports it? (beside it being black magic)

  • His implementation ensures you can't use anonymous delegates by checking for the presence of CompilerGeneratedAttribute on declaring type of the delegate's method. It could be a welcomed improvement in your library, because it's way too easy to erroneously subscribe to a lambda...


I put up the code-project's code in a new repo, and replaced the original ad-hoc benchmark with BenchmarkDotNet. I also added a benchmark for your library. Check it out! https://github.com/mlaily/FastSmartWeakEvent

Summary:

|                                 Method |      Mean |     Error |   StdDev | Ratio | RatioSD |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|--------------------------------------- |----------:|----------:|---------:|------:|--------:|-------:|------:|------:|----------:|
|                'Normal (strong) event' |  12.12 ns |  0.218 ns | 0.414 ns |  1.00 |    0.00 |      - |     - |     - |         - |
|                     'Smart weak event' | 594.21 ns |  9.563 ns | 7.467 ns | 47.41 |    0.98 | 0.0420 |     - |     - |     177 B |
| 'Fast smart weak event (2009 version)' |  41.49 ns |  0.839 ns | 1.030 ns |  3.36 |    0.12 | 0.0172 |     - |     - |      72 B |
| 'Fast smart weak event (2013 version)' |  18.16 ns |  0.157 ns | 0.131 ns |  1.45 |    0.04 |      - |     - |     - |         - |
|                    'Thomas weak event' | 567.82 ns | 10.375 ns | 9.705 ns | 45.64 |    1.33 | 0.1545 |     - |     - |     650 B |

EDIT: I almost forgot: he apparently rewrote the thing 4 years after his code-project article, but it seems to only live in a gist here: https://gist.github.com/dgrunwald/6445360#file-fastsmartweakevent-cs (I added it to my repo and benchmark)

Have a great day!

mlaily avatar Nov 04 '20 13:11 mlaily

Salut Melvyn,

Yes, I know about this article. To be honest, I don't remember exactly why I didn't use the same approach (or even just use his code directly...). Maybe there was something I couldn't do with it, but I don't remember what. Anyway, this project started as a POC to test an idea (using open-instance delegates), and ended up being used by many people, so I didn't rethink my approach. I agree that it's probably worth considering using reflection emit.

  • His implementation ensures you can't use anonymous delegates by checking for the presence of CompilerGeneratedAttribute on declaring type of the delegate's method. It could be a welcomed improvement in your library, because it's way too easy to erroneously subscribe to a lambda...

I'm not sure about that. Using a lambda is fine, as long as you keep a reference to it. But yes, it's easy to get wrong...

thomaslevesque avatar Nov 04 '20 17:11 thomaslevesque

Thanks for your answers!

Feel free to close this issue if you don't intend to implement these suggestions, or if you want to create more targeted issues for them :)

mlaily avatar Nov 04 '20 17:11 mlaily

Closing this issue, since it's pretty old and not seeing any activity. I have some plans to redesign this library using compile-time code generation, which would probably improve performance as well. But it depends on this being implemented in the compiler, and it's probably too late for the next release...

thomaslevesque avatar Apr 19 '24 02:04 thomaslevesque