Closed teo-tsirpanis closed 2 weeks ago
1) The removal of the InlineIL
and InlineMethod
dependencies should depend on the benchmark results. I think InlineIL
can be removed and if there are problems in older frameworks, we can leave the InlineIL
dependency and the old implementation for them. It is more difficult to remove InlineMethod
, because even .NET 8 benefits from its use. I created InlineMethod.Fody because the JIT inliner wasn't working well enough.
2) SafeHandle
change LGTM overall with some comments.
3) I'm not removing support for older frameworks yet as long as it costs almost nothing to support them. The code contains framework-dependent optimizations.
Oh you wrote InlineMethod
, nice! And I hadn't seen that there are optimizations for all targeted frameworks.
One advantage to targeting less frameworks is reduced package size; right now it is in 1.15MB, which is not yet but close to what I would call "big". But it's not the end of the world.
All feedback was addressed, and I also fixed a memory leak I spotted. I am going to run some benchmarks and will get back to you.
The results are in.
I am noticing a slight improvement for .NET 7 and 8, and either no change or a slight regression for some earlier frameworks. What do you think?
I'll run benchmarks later too. I also need to check that a .NET Native project builds with ZstdSharp
dependency, since there was a problem with that earlier. It may not support some modern c# stuff. See https://github.com/adamhathcock/sharpcompress/issues/793
My results:
Benchmarks LGTM.
A .NET Native project builds with ZstdSharp
dependency.
@teo-tsirpanis Thank you!
This PR:
InlineIL
package. All its uses can be replaced by theSystem.Runtime.CompilerServices.Unsafe
package or other built-in .NET APIs, and the replaced code is simpler.Compressor
andDecompressor
classes to use classes derived fromSafeHandle
to manage the ZSTD context pointers. While safe handles are usually used for interop with native code, we use them here in managed code to manage the lifetime of manually allocated memory. This makes the code simpler and much more reliable; you don't have to writeGC.KeepAlive
s anymore, and safe handles protect from cases like one thread callingDispose
while another thread uses the resource.null
. This is not valid code since spans are structs and not classes.