NightOwl888 commented on issue #1041: URL: https://github.com/apache/lucenenet/issues/1041#issuecomment-2517930777
> Before we "Claim" any performance penalty, could we please prove those? To qualify this, I am referring to the original conversation when we were talking about removing `netstandard2.1`. First of all, `netstandard2.0` shipped before there was a [`GetEnumerator()`](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.conditionalweaktable-2.system-collections-ienumerable-getenumerator?view=net-8.0#system-runtime-compilerservices-conditionalweaktable-2-system-collections-ienumerable-getenumerator) or [`AddOrUpdate()`](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.conditionalweaktable-2.addorupdate?view=net-8.0#system-runtime-compilerservices-conditionalweaktable-2-addorupdate(-0-1)) method on `ConditionalWeakTable<TKey, TValue>`. For `GetEnumerator()` we worked around by using Prism weak events (which we [recently added to the `Support` namespace](https://github.com/apache/lucenenet/pull/875)) and for `AddOrUpdate()`, we are using a `Remove()` followed by `Add()`. During experimentation, it was clear that using `WeakReference` (which is how the Prism weak events are implemented) holds onto references longer than using purely a `ConditionalWeakTable<TKey, TValue>`. However, there is a [`WeakEventManager`](https://github.com/apache/lucenenet/issues/872#issuecomment-1752122329) (from WPF) that exists only on .NET Framework that would probably perform better that uses another `ConditionalWeakTable<TKey, TValue>` along with some native code under the hood. The Prism weak events solution we have is the best we can do for `netstandard2.0` without dropping to native code. `Remove()` followed by `Add()` is also less efficient than `AddOrUpdate()`. Note that the `netstandard2.1` target primarily exists because of the missing APIs on `ConditionalWeakTable<TKey, TValue>`. Secondly, and more importantly, when the `netstandard2.0` target is chosen, all of its dependencies can only target `netstandard2.0` or lower. If the runtime is `net8.0` or `net9.0` and Lucene.Net is `netstandard2.0`, it will no longer call the hardware intrinsics APIs that didn't exist until `net6.0` because it will load `System.Memory` and `J2N` assemblies that target `netstandard2.0`. System.Memory and J2N both use hardware intrinsics only if the target is .NET Core. And this goes well beyond those two dependencies. As for the difference between `net462` and `netstandard2.0`, the performance advantage is not as significant in that case. Although, there are still a few optimizations with having a native runtime target over a .NET Standard target. Do I think that we should drop `netstandard2.0`? Not at this time. But I think we should consider doing it before we drop `netstandard2.1` because of the missing APIs on `ConditionalWeakTable<TKey, TValue>`. However, as long as Microsoft is still targeting `netstandard2.0` it is a strong indicator that we should be, as well. That being said, I think we should actively discourage anyone from using `netstandard2.0` as a way to target both .NET Framework and .NET Core, because doing so loses several of the performance advantages of using .NET Core (at least for our class libraries and any class libraries we depend on). That is, unless you are swapping in the .NET Core assembly into the final build (although, there may be some minor API differences where you could get burned by doing that). -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: dev-unsubscr...@lucenenet.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org