StringCollection uses ArrayList as a backing collection. The current stringlist enumerator is a reference type. By adopting a private version for the current state of StringCollection as is present in List<> we can cut enumeration times in half and avoid allocating by ignoring the ArrayList enumerator and use a variant of the List<> enumerator. Also, the ArrayList indexer can easily avoid one range check by using the optimization present in the List<> indexer:
if((uint)index >= (uint)_size) throw...
Finally, to the best of my knowledge methods which throw directly are not inlined. The ArrayList Indexer throws, unlike the List<> Indexer which uses a throw helper. We should also introduce a throwhelper for ArrayList
methods which throw directly are not inlined
Technically it can be inlined; it's just because the throwing part leads to more instructions and can bring the method size huge enough that JIT will not inline the whole method.
can't you just substitute List<string> directly where StringCollection is used? I think they have all the members that are identical in both names and behaviours. If the codes are something you in charge of you should be able to just do using StringCollection = System.Collections.Generic.List<string>;.
I don't think both StringCollection and ArrayLists are actively maintained (or in consideration), apart from bug fixes.
We inherited a library that was compiled for wpf on net core which uses these classes extensively. We are not the owners of that library, thus can not make changes to it. It would be beneficial if we could improve the performance for these types for scenarios similar to ours.
Changing the return type of GetEnumerator would be a breaking change, so I don't think this will be possible.
the throwing part leads to more instructions and can bring the method size huge enough that JIT will not inline the whole method.
Just a note, any method that throws is ineligible for inlining. This is why you'll often see dedicated throwing methods in corefx.
Just a note, any method that throws is ineligible for inlining.
I don't believe this is true anymore.
I don't believe this is true anymore.
@AndyAyersMS can speak to this, but my assumption is that the "throwing" part may no longer be an issue but instantiating an exception requires a fair bit of IL and that can make the method too large to inline.
edit: I didn't notice I just repeated @Gnbrkm41
By default the jit won't inline small methods like throw helpers that unconditionally (directly) throw because there is generally no benefit to such an inline.
Methods that conditionally throw can be inlined, subject to other heuristics. Methods that directly throw will be inlined if marked with AggressiveInlining.
The throw helper pattern you see in corefx/coreclr helps to reduce overall code size when a given exception can be thrown from multiple places in the code.
Most helpful comment
By default the jit won't inline small methods like throw helpers that unconditionally (directly) throw because there is generally no benefit to such an inline.
Methods that conditionally throw can be inlined, subject to other heuristics. Methods that directly throw will be inlined if marked with
AggressiveInlining.The throw helper pattern you see in corefx/coreclr helps to reduce overall code size when a given exception can be thrown from multiple places in the code.