NightOwl888 commented on PR #1108: URL: https://github.com/apache/lucenenet/pull/1108#issuecomment-2604677372
1. True, which is why we tried avoiding that by cascading the call to a wraped BCL implementation previously. Unfortunately, the tradeoff is that prior to .NET Core 3.x there was no support for deletion while iterating forward which Lucene uses in a few places. So, we either have to conditionally compile or make a normalized implementation in J2N. IMO, it is better to have a normalized implementation so we can push as many conditional compilation statements into J2N as possible until such time we don't need the J2N implementation any longer (in this case, when we drop support for everything below .NET Core). But, I don't think we should use `JCG.Dictionary<TKey, TValue>` unless it is required. 2. All I am saying is that the next release of Lucene.NET will not have a reference to J2N 2.1, so this comparison is not completely accurate as to what will be released and does not account for work that already exists on the `main` branch in J2N. In the benchmark the compiler `foreach` calls `SCG.Dictionary<TKey, TValue>.Values.GetEnumerator()`, which returns type `SCG.Dictionary<TKey, TValue>.ValueCollection.Enumerator`, a struct. The J2N implementation also returns a struct, but casts it to an `IEnumerator<TValue>`, which will box. To do a direct comparison, the dictionary should be using the interface `IDictionary<string, string> values = new Dictionary<string, string>();` so the box happens there, also. In J2N 3.0, this boxing will go away so the concrete types will return a struct which will match the upstream performance better. Also, J2N 2.1 had some boxing in some of the guard clauses, which was [recently fixed](https://github.com/NightOwl888/J2N/pull/127) as well as using the [unsigned right shift operator instead of a method](https://github.com/NightOwl888/J2N/pull/116). These will have a positive impact on the performance of much of the J2N library, including the collections. 3. Good point on the difference in hardware. That could be causing the warnings I am seeing. Of course, that makes me cautious about seeing results from others that don't have at least 100ms of work in the benchmark.  #### .NET Framework There is one other difference that could explain what you are seeing on .NET Framework. We patched the implementation to nullify the data buckets only for reference types, whereas .NET Framework did it for both value and reference types. There is a method called `RuntimeHelpers.IsReferenceOrContainsReferences<T>()` that is used to determine whether there are any reference types to nullify, but it doesn't exist on .NET Framework so we use Reflection to analyze the type and cache the value the first time a type is used. More iterations would definitely change the result because that Reflection overhead only happens on the first call. Here is the implementation: https://github.com/NightOwl888/J2N/blob/8845a696e2cd3e2ca0752823c779c72aa7f0e5a1/src/J2N/Runtime/CompilerServices/RuntimeHelper.cs#L31-L84 So, 2 ways we could deal with this: - Review the above implementation to see if there are any performance enhancements that could be made - Change it to always clean up references the collection buckets as was the case in .NET Framework but keep the enhancement where `RuntimeHelpers.IsReferenceOrContainsReferences<T>()` exists (which would require conditional compilation in the J2N collections) #### .NET 9 Implementation Actually, it is possible that the difference between `net8.0` and `net9.0` is due to a more efficient `.ToArray()` implementation and this might have little or nothing to do with enhancements to the `Dictionary<TKey, TValue>` implementation. -- 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