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

Reply via email to