MoreLINQ icon indicating copy to clipboard operation
MoreLINQ copied to clipboard

Update argument validation to favour JIT in-lining

Open viceroypenguin opened this issue 2 years ago • 3 comments

In most operators, we have guard statements that are executed immediately, while the bulk of the operator is implemented in a separate method (see #837 for discussion on why this pattern is used). Currently, the guard statements cannot be inlined to the calling method. This is because throw statements are used directly, and throw statements prevent the JIT from inlining any method.

We should move guard statements to separate methods, which would allow them to be inlined in release builds. In some cases, this would be that due to available context information to the JIT, they can be eliminated entirely and the final JIT code only has a direct call to the internal operator code.

Personal recommendation: add a reference to CommunityToolkit.Diagnostics, and update all guard statements to these. This would allow us to rely on a shared implementation of this boilerplate code and if others do as well, then that is mutual code shared.

Alternative recommendation: Add our own Guard and ThrowHelper methods and update all guard statements to these. This would duplicate code that could be shared, but not add a dependency on another library.

viceroypenguin avatar Nov 25 '22 20:11 viceroypenguin

This would be a welcomed addition.

Is this something you want to help with by submitting a PR?

I'm all for reuse if something exists, done well and actively maintained, and CommunityToolkit.Diagnostics seems to tick all those boxes. However, it doesn't support .NET Framework and .NET Standard 1.0 so the only way I see using the package here is to contribute the necessary changes back to the package's repo that would enable those targets. Since that could take time or get push back, the alternative would be to bring in the sources here and sync them when there is a new release. Hopefully, the source may not need much change so they can be easily synchronised without needing to redo the changes. Perhaps something that could help here is conditionally compiled sections that would be contributed back (like the unsafe parts?). My guess is that we won't need much from the package except maybe null and numeric range checks so taking inspiration or just copying (with due credit) the relevant bits won't need much on-going maintenance or synchronisation and would also avoid a dependency.

atifaziz avatar Jan 22 '23 14:01 atifaziz

As far as CommunityToolkit.Diagnostics support goes, it supports netstandard2.0, which implicitly supports net462. Given that we've dropped support for anything pre-net462, I'm not sure we care about pre-netstandard2.0?

viceroypenguin avatar Jan 23 '23 18:01 viceroypenguin

Given that we've dropped support for anything pre-net462, I'm not sure we care about pre-netstandard2.0?

That's a fair point!

atifaziz avatar Jan 24 '23 18:01 atifaziz