Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map: comparer optimization #10855

Closed
wants to merge 13 commits into from
Closed

Map: comparer optimization #10855

wants to merge 13 commits into from

Conversation

buybackoff
Copy link
Contributor

@buybackoff buybackoff commented Jan 8, 2021

Copied from comment #10845 (comment) to show the code and run CI

Map/Set always use the default comparison. It should be easy to optimize it... One may think... But I've seen #9348, #513, and related. Such a hopeless state to optimize (inline/devirtualize) the comparison :(

This implementation is probably not 100% compatible with the current behavior. It could be if we apply the logic from #9348 snippet, to exclude records & DUs, if that code is correct.

If we take the current NuGet 5.0 release without any changes to Map as a baseline, are we ready to (Ratio column)

  • [Improve the map performance with] primitive keys by 3.65x - getItem,
  • .. struct T : IComparable<T> by 4.14x - getItemIntLike,
  • .. struct records by 95% - getItemIntRecord
  • .. string by 52% - getItemString,
  • but lose 15% for reference types - getItemRefLike, 17% for reference type records - getItemIntRefRecord

?

I would say that everything could be wrapped by struct T : IComparable<T> + efficient logic there, and if someone uses ref-types as a key they do care about about performance by definition. But I do understand that regressing existing code by 15/17% may be too big. Yet the tradeoff is so great for primitive types.

What do you think? What's the most important use case for the map/set?

The types in the bench are:

    [<StructuralEquality;CustomComparison>]
    type IntLike =
        struct
           val Value: int
           new(v:int) = {Value = v}
           member x.CompareTo(y:IntLike) = x.Value.CompareTo(y.Value)
        end
        
        interface IComparable<IntLike> with
            member x.CompareTo(y) = x.CompareTo(y)
            
        interface IComparable with
            member x.CompareTo(y) = x.CompareTo(y :?> IntLike) 


    type RefLike =
        val Value: int
        new(v:int) = {Value = v}
        member x.CompareTo(y:RefLike) = x.Value.CompareTo(y.Value)
        
        interface IComparable<RefLike> with
            member x.CompareTo(y) = x.CompareTo(y)
            
        interface IComparable with
            member x.CompareTo(y) = x.CompareTo(y :?> RefLike)
            
    [<Struct>]
    type IntRecord =
          { Value1 : int
            Value2 : int
          }

    type IntRefRecord =
          { Value1 : int
            Value2 : int
          }
Method Job BuildConfiguration Size Mean Error StdDev Ratio RatioSD Rank Gen 0 Gen 1 Gen 2 Allocated
getItem After After 100 20.48 ns 0.935 ns 0.243 ns 1.00 0.00 1 - - - -
getItem Main50 Main50 100 29.40 ns 0.728 ns 0.189 ns 1.44 0.02 2 - - - -
getItem NuGet50 NuGet50 100 74.83 ns 6.092 ns 0.943 ns 3.65 0.08 3 - - - -
getItemIntLike After After 100 60.45 ns 0.460 ns 0.119 ns 1.00 0.00 1 - - - -
getItemIntLike Main50 Main50 100 220.00 ns 4.159 ns 0.644 ns 3.64 0.02 2 0.0450 - - 283 B
getItemIntLike NuGet50 NuGet50 100 250.34 ns 9.453 ns 1.463 ns 4.14 0.03 3 0.0449 - - 283 B
getItemString After After 100 76.03 ns 1.027 ns 0.267 ns 1.00 0.00 2 - - - -
getItemString Main50 Main50 100 68.22 ns 0.538 ns 0.083 ns 0.90 0.00 1 - - - -
getItemString NuGet50 NuGet50 100 115.77 ns 0.626 ns 0.162 ns 1.52 0.01 3 - - - -
getItemRefLike After After 100 278.41 ns 3.569 ns 0.927 ns 1.00 0.00 3 - - - -
getItemRefLike Main50 Main50 100 200.05 ns 6.346 ns 1.648 ns 0.72 0.01 1 - - - -
getItemRefLike NuGet50 NuGet50 100 236.40 ns 3.194 ns 0.494 ns 0.85 0.00 2 - - - -
getItemIntRecord After After 100 113.75 ns 5.312 ns 1.380 ns 1.00 0.00 1 - - - -
getItemIntRecord Main50 Main50 100 200.78 ns 1.451 ns 0.224 ns 1.77 0.02 2 0.0449 - - 283 B
getItemIntRecord NuGet50 NuGet50 100 221.77 ns 4.146 ns 1.077 ns 1.95 0.03 3 0.0450 - - 283 B
getItemIntRefRecord After After 100 255.08 ns 5.493 ns 1.427 ns 1.00 0.00 3 - - - -
getItemIntRefRecord Main50 Main50 100 173.02 ns 3.398 ns 0.883 ns 0.68 0.01 1 - - - -
getItemIntRefRecord NuGet50 NuGet50 100 211.41 ns 2.625 ns 0.406 ns 0.83 0.01 2 - - - -

Store height in leaves. Compared to the old discussion, when Left/Right were proposed to be stored in a universal node,
this adds 4 bytes to leaves or 2 bytes per item on average (vs 16/8).
`Match` produces `sub 1` and `switch` instruction. Here, for any non-trivial count,
nodes are more frequent than leaves on the path, so branch prediction should be beneficial.

else if Type.op_Equality(typeof<'T>, typeof<bool>) then unbox<bool>(box(l)).CompareTo(unbox<bool>(box(r)))
else if Type.op_Equality(typeof<'T>, typeof<char>) then unbox<char>(box(l)).CompareTo(unbox<char>(box(r)))
else if Type.op_Equality(typeof<'T>, typeof<float>) then unbox<float>(box(l)).CompareTo(unbox<float>(box(r)))
Copy link
Contributor Author

@buybackoff buybackoff Jan 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

floats have non-standard treatment in F#, should remove these lines or replicate the behavior

@buybackoff
Copy link
Contributor Author

buybackoff commented Jan 9, 2021

This is what we could get if using:

  • static read-only field that indicates if a type implements IComparable<T>, like this
  • a custom IL that add .constained modified to callvirt CompareTo when the static field is true (not sure if that is verifiable), like this.
    type CompareHelper<'T when 'T : comparison>() =
        static let c = LanguagePrimitives.FastGenericComparer

        [<MethodImpl(MethodImplOptions.AggressiveInlining)>]
        static member Compare(l:'T, r:'T):int =
            if Spreads.KeyComparer<'T>.IsIComparable then // JIT-time constant
                // add .constained before callvirt to IComparable.CompareTo
                Spreads.Native.UnsafeEx.CompareToConstrained(&Unsafe.AsRef(&l),&Unsafe.AsRef(&r))
            else
                // with IsIComparable as constant all other cases use IComparer directly, as before
                c.Compare(l, r)
Method Job BuildConfiguration Size Mean Error StdDev Ratio RatioSD Rank Gen 0 Gen 1 Gen 2 Allocated
getItem After After 100 19.22 ns 0.732 ns 0.190 ns 1.00 0.00 1 - - - -
getItem Main50 Main50 100 28.86 ns 0.168 ns 0.026 ns 1.50 0.02 2 - - - -
getItem NuGet50 NuGet50 100 73.80 ns 0.585 ns 0.152 ns 3.84 0.04 3 - - - -
getItemIntLike After After 100 48.77 ns 1.409 ns 0.366 ns 1.00 0.00 1 - - - -
getItemIntLike Main50 Main50 100 215.65 ns 3.189 ns 0.828 ns 4.42 0.04 2 0.0448 - - 283 B
getItemIntLike NuGet50 NuGet50 100 248.46 ns 3.763 ns 0.582 ns 5.09 0.05 3 0.0445 - - 283 B
getItemString After After 100 77.26 ns 0.935 ns 0.243 ns 1.00 0.00 2 - - - -
getItemString Main50 Main50 100 68.54 ns 1.239 ns 0.322 ns 0.89 0.01 1 - - - -
getItemString NuGet50 NuGet50 100 114.88 ns 1.200 ns 0.312 ns 1.49 0.00 3 - - - -
getItemRefLike After After 100 132.77 ns 1.419 ns 0.369 ns 1.00 0.00 1 - - - -
getItemRefLike Main50 Main50 100 200.83 ns 4.727 ns 1.228 ns 1.51 0.01 2 - - - -
getItemRefLike NuGet50 NuGet50 100 236.52 ns 7.414 ns 1.147 ns 1.78 0.01 3 - - - -
getItemIntRecord After After 100 93.29 ns 0.634 ns 0.098 ns 1.00 0.00 1 - - - -
getItemIntRecord Main50 Main50 100 199.74 ns 8.888 ns 1.375 ns 2.14 0.01 2 0.0444 - - 283 B
getItemIntRecord NuGet50 NuGet50 100 222.91 ns 7.227 ns 1.118 ns 2.39 0.01 3 0.0443 - - 283 B
getItemIntRefRecord After After 100 137.51 ns 1.681 ns 0.436 ns 1.00 0.00 1 - - - -
getItemIntRefRecord Main50 Main50 100 176.34 ns 7.543 ns 1.167 ns 1.28 0.01 2 - - - -
getItemIntRefRecord NuGet50 NuGet50 100 211.85 ns 2.063 ns 0.319 ns 1.54 0.01 3 - - - -

@buybackoff
Copy link
Contributor Author

Here are the numbers if we only use static readonly and a delegate from reflection.

        [<MethodImpl(MethodImplOptions.AggressiveInlining)>]
        static member Compare(l:'T, r:'T):int =
            if Spreads.KeyComparer<'T>.IsIComparable then
                CompareHelper<'T>.CompareToDlg.Invoke(l,r)
            else
                c.Compare(l, r)

But this time delegates are used for ref-type IComparables

        static member val CompareToDlg : Func<'T,'T,int> =
                let dlg =
                    try
                        if Spreads.KeyComparer<'T>.IsIComparable then // All types, not only structs
                            let dlg = ...
                            dlg
                        else
                            null
                    with _ -> null
                dlg
            with get

Both RefLike and normal record do implement IComparable, and they have significant improvement.

Method Job BuildConfiguration Size Mean Error StdDev Ratio RatioSD Rank Gen 0 Gen 1 Gen 2 Allocated
getItem After After 100 19.19 ns 0.900 ns 0.234 ns 1.00 0.00 1 - - - -
getItem Main50 Main50 100 30.90 ns 0.681 ns 0.177 ns 1.61 0.02 2 - - - -
getItem NuGet50 NuGet50 100 74.52 ns 2.275 ns 0.591 ns 3.88 0.03 3 - - - -
getItemIntLike After After 100 75.48 ns 0.582 ns 0.090 ns 1.00 0.00 1 - - - -
getItemIntLike Main50 Main50 100 212.54 ns 2.125 ns 0.552 ns 2.82 0.01 2 0.0448 - - 283 B
getItemIntLike NuGet50 NuGet50 100 239.88 ns 5.860 ns 1.522 ns 3.18 0.03 3 0.0445 - - 283 B
getItemString After After 100 85.00 ns 1.163 ns 0.302 ns 1.00 0.00 2 - - - -
getItemString Main50 Main50 100 64.90 ns 1.165 ns 0.302 ns 0.76 0.01 1 - - - -
getItemString NuGet50 NuGet50 100 121.30 ns 1.856 ns 0.482 ns 1.43 0.01 3 - - - -
getItemRefLike After After 100 158.81 ns 5.556 ns 0.860 ns 1.00 0.00 1 - - - -
getItemRefLike Main50 Main50 100 190.16 ns 3.069 ns 0.475 ns 1.20 0.01 2 - - - -
getItemRefLike NuGet50 NuGet50 100 237.65 ns 2.540 ns 0.660 ns 1.50 0.01 3 - - - -
getItemIntRecord After After 100 118.74 ns 1.572 ns 0.408 ns 1.00 0.00 1 - - - -
getItemIntRecord Main50 Main50 100 201.83 ns 2.546 ns 0.661 ns 1.70 0.01 2 0.0443 - - 283 B
getItemIntRecord NuGet50 NuGet50 100 223.86 ns 4.687 ns 0.725 ns 1.88 0.01 3 0.0448 - - 283 B
getItemIntRefRecord After After 100 162.28 ns 2.088 ns 0.323 ns 1.00 0.00 1 - - - -
getItemIntRefRecord Main50 Main50 100 174.75 ns 10.652 ns 1.648 ns 1.08 0.01 2 - - - -
getItemIntRefRecord NuGet50 NuGet50 100 213.88 ns 7.739 ns 2.010 ns 1.32 0.01 3 - - - -

@buybackoff
Copy link
Contributor Author

It works quite well now, without static readonly and custom IL.

Related to the changes is fsharp/fslang-suggestions#816. We use IComparable<T> if it is assignable from T, i.e. T implements it.

Strange thing happens with string vs the previous PR, but compared to the base line the improvement is still big.

Previous benchmarks were not correct for some cases in absolute terms (e.g. wrong number of OperationsPerInvoke), but relatively were OK. The updated Map benchmarks are here: https://github.com/buybackoff/fsharp-benchmarks

Method Job BuildConfiguration Size Mean Error StdDev Ratio RatioSD Rank Gen 0 Gen 1 Gen 2 Allocated
getItemInt After After 10 12.82 ns 0.269 ns 0.070 ns 1.00 0.00 1 - - - -
getItemInt Main50 Main50 10 18.22 ns 1.041 ns 0.270 ns 1.42 0.02 2 - - - -
getItemInt NuGet50 NuGet50 10 37.81 ns 0.398 ns 0.103 ns 2.95 0.02 3 - - - -
getItemIntLike After After 10 31.17 ns 0.388 ns 0.060 ns 1.00 0.00 1 - - - -
getItemIntLike Main50 Main50 10 125.00 ns 6.831 ns 1.774 ns 4.03 0.04 2 0.0267 - - 168 B
getItemIntLike NuGet50 NuGet50 10 147.13 ns 4.833 ns 1.255 ns 4.73 0.03 3 0.0263 - - 168 B
getItemString After After 10 31.12 ns 0.209 ns 0.032 ns 1.00 0.00 2 - - - -
getItemString Main50 Main50 10 26.75 ns 1.151 ns 0.299 ns 0.86 0.01 1 - - - -
getItemString NuGet50 NuGet50 10 54.44 ns 0.705 ns 0.183 ns 1.75 0.00 3 - - - -
getItemRefLike After After 10 73.33 ns 1.690 ns 0.439 ns 1.00 0.00 1 - - - -
getItemRefLike Main50 Main50 10 122.63 ns 0.830 ns 0.215 ns 1.67 0.01 2 - - - -
getItemRefLike NuGet50 NuGet50 10 148.46 ns 0.961 ns 0.149 ns 2.03 0.01 3 - - - -
getItemIntRecord After After 10 56.95 ns 1.639 ns 0.426 ns 1.00 0.00 1 - - - -
getItemIntRecord Main50 Main50 10 114.25 ns 1.843 ns 0.479 ns 2.01 0.01 2 0.0268 - - 168 B
getItemIntRecord NuGet50 NuGet50 10 134.20 ns 1.453 ns 0.225 ns 2.36 0.02 3 0.0263 - - 168 B
getItemIntRefRecord After After 10 75.23 ns 3.740 ns 0.971 ns 1.00 0.00 1 - - - -
getItemIntRefRecord Main50 Main50 10 104.20 ns 1.346 ns 0.349 ns 1.39 0.01 2 - - - -
getItemIntRefRecord NuGet50 NuGet50 10 127.67 ns 1.501 ns 0.232 ns 1.70 0.02 3 - - - -
getItemIntLikeNonGenCmp After After 10 47.39 ns 2.249 ns 0.584 ns 1.00 0.00 1 0.0133 - - 84 B
getItemIntLikeNonGenCmp Main50 Main50 10 122.17 ns 1.105 ns 0.171 ns 2.57 0.03 2 0.0263 - - 168 B
getItemIntLikeNonGenCmp NuGet50 NuGet50 10 142.20 ns 2.236 ns 0.581 ns 3.00 0.04 3 0.0262 - - 168 B
getItemRefLikeNonGenCmp After After 10 97.35 ns 2.416 ns 0.628 ns 1.00 0.00 1 - - - -
getItemRefLikeNonGenCmp Main50 Main50 10 122.37 ns 1.477 ns 0.229 ns 1.26 0.01 2 - - - -
getItemRefLikeNonGenCmp NuGet50 NuGet50 10 147.73 ns 2.022 ns 0.313 ns 1.52 0.01 3 - - - -
containsKeyInt After After 10 11.80 ns 0.698 ns 0.108 ns 1.00 0.00 1 - - - -
containsKeyInt Main50 Main50 10 14.16 ns 0.311 ns 0.048 ns 1.20 0.01 2 - - - -
containsKeyInt NuGet50 NuGet50 10 34.87 ns 1.011 ns 0.263 ns 2.95 0.04 3 - - - -
containsKeyIntLike After After 10 28.34 ns 1.342 ns 0.208 ns 1.00 0.00 1 - - - -
containsKeyIntLike Main50 Main50 10 114.22 ns 2.457 ns 0.638 ns 4.03 0.01 2 0.0266 - - 168 B
containsKeyIntLike NuGet50 NuGet50 10 144.45 ns 5.236 ns 1.360 ns 5.09 0.07 3 0.0265 - - 168 B
containsKeyString After After 10 30.09 ns 1.165 ns 0.180 ns 1.00 0.00 2 - - - -
containsKeyString Main50 Main50 10 24.20 ns 0.670 ns 0.174 ns 0.80 0.01 1 - - - -
containsKeyString NuGet50 NuGet50 10 49.48 ns 1.291 ns 0.335 ns 1.65 0.00 3 - - - -
containsKeyRefLike After After 10 74.45 ns 4.001 ns 1.039 ns 1.00 0.00 1 - - - -
containsKeyRefLike Main50 Main50 10 117.72 ns 2.011 ns 0.311 ns 1.58 0.02 2 - - - -
containsKeyRefLike NuGet50 NuGet50 10 150.47 ns 2.439 ns 0.377 ns 2.02 0.03 3 - - - -
containsKeyIntRecord After After 10 54.18 ns 0.445 ns 0.069 ns 1.00 0.00 1 - - - -
containsKeyIntRecord Main50 Main50 10 109.51 ns 1.518 ns 0.394 ns 2.02 0.01 2 0.0267 - - 168 B
containsKeyIntRecord NuGet50 NuGet50 10 127.24 ns 2.166 ns 0.562 ns 2.35 0.01 3 0.0267 - - 168 B
containsKeyIntRefRecord After After 10 75.88 ns 1.335 ns 0.207 ns 1.00 0.00 1 - - - -
containsKeyIntRefRecord Main50 Main50 10 100.98 ns 1.748 ns 0.454 ns 1.33 0.01 2 - - - -
containsKeyIntRefRecord NuGet50 NuGet50 10 126.92 ns 4.102 ns 1.065 ns 1.67 0.01 3 - - - -
containsKeyIntLikeNonGenCmp After After 10 43.01 ns 1.490 ns 0.231 ns 1.00 0.00 1 0.0133 - - 84 B
containsKeyIntLikeNonGenCmp Main50 Main50 10 117.52 ns 2.215 ns 0.343 ns 2.73 0.01 2 0.0264 - - 168 B
containsKeyIntLikeNonGenCmp NuGet50 NuGet50 10 143.99 ns 4.625 ns 0.716 ns 3.35 0.02 3 0.0267 - - 168 B
containsKeyRefLikeNonGenCmp After After 10 91.62 ns 2.524 ns 0.655 ns 1.00 0.00 1 - - - -
containsKeyRefLikeNonGenCmp Main50 Main50 10 117.78 ns 4.052 ns 1.052 ns 1.29 0.01 2 - - - -
containsKeyRefLikeNonGenCmp NuGet50 NuGet50 10 148.57 ns 0.909 ns 0.141 ns 1.62 0.01 3 - - - -
itemCountInt After After 10 24.64 ns 0.530 ns 0.138 ns 1.00 0.00 2 - - - -
itemCountInt Main50 Main50 10 21.32 ns 0.547 ns 0.142 ns 0.87 0.01 1 - - - -
itemCountInt NuGet50 NuGet50 10 66.16 ns 0.502 ns 0.078 ns 2.68 0.01 3 - - - -
itemCountIntLike After After 10 24.60 ns 0.361 ns 0.094 ns 1.00 0.00 2 - - - -
itemCountIntLike Main50 Main50 10 21.28 ns 0.140 ns 0.036 ns 0.87 0.00 1 - - - -
itemCountIntLike NuGet50 NuGet50 10 65.35 ns 1.491 ns 0.387 ns 2.66 0.02 3 - - - -
itemCountString After After 10 29.24 ns 1.547 ns 0.402 ns 1.00 0.00 1 - - - -
itemCountString Main50 Main50 10 32.80 ns 1.913 ns 0.497 ns 1.12 0.02 2 - - - -
itemCountString NuGet50 NuGet50 10 94.59 ns 1.625 ns 0.251 ns 3.23 0.04 3 - - - -
itemCountRefLike After After 10 22.83 ns 0.516 ns 0.080 ns 1.00 0.00 1 - - - -
itemCountRefLike Main50 Main50 10 29.12 ns 0.257 ns 0.040 ns 1.28 0.00 2 - - - -
itemCountRefLike NuGet50 NuGet50 10 72.46 ns 2.806 ns 0.729 ns 3.17 0.03 3 - - - -
itemCountIntRecord After After 10 24.84 ns 0.903 ns 0.235 ns 1.00 0.00 2 - - - -
itemCountIntRecord Main50 Main50 10 21.27 ns 0.481 ns 0.074 ns 0.86 0.01 1 - - - -
itemCountIntRecord NuGet50 NuGet50 10 65.32 ns 1.707 ns 0.443 ns 2.63 0.04 3 - - - -
itemCountIntRefRecord After After 10 22.86 ns 0.512 ns 0.133 ns 1.00 0.00 1 - - - -
itemCountIntRefRecord Main50 Main50 10 29.15 ns 0.289 ns 0.075 ns 1.28 0.01 2 - - - -
itemCountIntRefRecord NuGet50 NuGet50 10 72.75 ns 2.803 ns 0.434 ns 3.19 0.01 3 - - - -
itemCountIntLikeNonGenCmp After After 10 24.68 ns 0.488 ns 0.127 ns 1.00 0.00 2 - - - -
itemCountIntLikeNonGenCmp Main50 Main50 10 21.37 ns 0.245 ns 0.038 ns 0.87 0.00 1 - - - -
itemCountIntLikeNonGenCmp NuGet50 NuGet50 10 64.76 ns 0.779 ns 0.121 ns 2.62 0.01 3 - - - -
itemCountRefLikeNonGenCmp After After 10 23.11 ns 0.667 ns 0.173 ns 1.00 0.00 1 - - - -
itemCountRefLikeNonGenCmp Main50 Main50 10 29.25 ns 0.700 ns 0.182 ns 1.27 0.01 2 - - - -
itemCountRefLikeNonGenCmp NuGet50 NuGet50 10 72.74 ns 3.487 ns 0.540 ns 3.15 0.01 3 - - - -
iterForeachInt After After 10 340.84 ns 3.626 ns 0.561 ns 1.00 0.00 1 0.1200 - - 760 B
iterForeachInt Main50 Main50 10 345.94 ns 13.114 ns 3.406 ns 1.02 0.01 1 0.1204 - - 760 B
iterForeachInt NuGet50 NuGet50 10 408.34 ns 7.207 ns 1.872 ns 1.20 0.01 2 0.1143 - - 720 B
iterForeachIntLike After After 10 341.02 ns 7.056 ns 1.832 ns 1.00 0.00 1 0.1206 - - 760 B
iterForeachIntLike Main50 Main50 10 343.78 ns 4.780 ns 1.241 ns 1.01 0.01 1 0.1198 - - 760 B
iterForeachIntLike NuGet50 NuGet50 10 415.43 ns 20.087 ns 5.216 ns 1.22 0.01 2 0.1197 - - 760 B
iterForeachString After After 10 483.92 ns 31.066 ns 8.068 ns 1.00 0.00 1 0.1401 - - 888 B
iterForeachString Main50 Main50 10 474.50 ns 16.711 ns 4.340 ns 0.98 0.01 1 0.1401 - - 888 B
iterForeachString NuGet50 NuGet50 10 662.15 ns 26.546 ns 6.894 ns 1.37 0.02 2 0.1414 - - 888 B
iterForeachRefLike After After 10 433.02 ns 4.705 ns 1.222 ns 1.00 0.00 1 0.1191 - - 760 B
iterForeachRefLike Main50 Main50 10 439.69 ns 12.488 ns 1.933 ns 1.02 0.00 2 0.1193 - - 760 B
iterForeachRefLike NuGet50 NuGet50 10 603.15 ns 16.566 ns 4.302 ns 1.39 0.01 3 0.1192 - - 760 B
iterForeachIntRecord After After 10 347.01 ns 20.020 ns 5.199 ns 1.00 0.00 1 0.1197 - - 760 B
iterForeachIntRecord Main50 Main50 10 341.07 ns 4.461 ns 0.690 ns 0.98 0.01 1 0.1195 - - 760 B
iterForeachIntRecord NuGet50 NuGet50 10 424.27 ns 6.502 ns 1.689 ns 1.22 0.02 2 0.1210 - - 760 B
iterForeachIntRefRecord After After 10 444.85 ns 9.004 ns 1.393 ns 1.00 0.00 1 0.1211 - - 760 B
iterForeachIntRefRecord Main50 Main50 10 447.96 ns 94.596 ns 24.566 ns 1.02 0.06 1 0.1198 - - 760 B
iterForeachIntRefRecord NuGet50 NuGet50 10 615.27 ns 41.290 ns 10.723 ns 1.38 0.03 2 0.1205 - - 760 B
iterForeachIntLikeNonGenCmp After After 10 336.76 ns 7.874 ns 2.045 ns 1.00 0.00 1 0.1200 - - 760 B
iterForeachIntLikeNonGenCmp Main50 Main50 10 345.60 ns 2.811 ns 0.435 ns 1.02 0.01 2 0.1198 - - 760 B
iterForeachIntLikeNonGenCmp NuGet50 NuGet50 10 406.77 ns 6.882 ns 1.065 ns 1.21 0.01 3 0.1193 - - 760 B
iterForeachRefLikeNonGenCmp After After 10 426.80 ns 12.058 ns 3.131 ns 1.00 0.00 1 0.1208 - - 760 B
iterForeachRefLikeNonGenCmp Main50 Main50 10 436.47 ns 15.438 ns 4.009 ns 1.02 0.01 2 0.1194 - - 760 B
iterForeachRefLikeNonGenCmp NuGet50 NuGet50 10 601.39 ns 20.317 ns 5.276 ns 1.41 0.01 3 0.1205 - - 760 B
addItemInt After After 10 72.52 ns 1.264 ns 0.328 ns 1.00 0.00 1 0.0308 - - 194 B
addItemInt Main50 Main50 10 86.28 ns 8.566 ns 2.225 ns 1.19 0.03 2 0.0321 - - 202 B
addItemInt NuGet50 NuGet50 10 156.38 ns 3.177 ns 0.492 ns 2.15 0.01 3 0.0315 - - 198 B
addItemIntLike After After 10 89.76 ns 0.966 ns 0.150 ns 1.00 0.00 1 0.0306 - - 194 B
addItemIntLike Main50 Main50 10 185.77 ns 10.286 ns 1.592 ns 2.07 0.02 2 0.0586 - - 370 B
addItemIntLike NuGet50 NuGet50 10 272.67 ns 6.496 ns 1.687 ns 3.04 0.01 3 0.0581 - - 370 B
addItemString After After 10 100.96 ns 1.229 ns 0.319 ns 1.00 0.00 2 0.0302 - - 190 B
addItemString Main50 Main50 10 98.17 ns 3.380 ns 0.878 ns 0.97 0.01 1 0.0317 - - 199 B
addItemString NuGet50 NuGet50 10 208.42 ns 8.470 ns 2.200 ns 2.06 0.02 3 0.0314 - - 199 B
addItemRefLike After After 10 146.04 ns 4.998 ns 1.298 ns 1.00 0.00 1 0.0306 - - 194 B
addItemRefLike Main50 Main50 10 200.82 ns 9.222 ns 1.427 ns 1.37 0.01 2 0.0318 - - 202 B
addItemRefLike NuGet50 NuGet50 10 328.08 ns 16.192 ns 4.205 ns 2.25 0.03 3 0.0321 - - 202 B
addItemIntRecord After After 10 122.37 ns 4.959 ns 0.767 ns 1.00 0.00 1 0.0304 - - 194 B
addItemIntRecord Main50 Main50 10 178.96 ns 2.040 ns 0.316 ns 1.46 0.01 2 0.0585 - - 370 B
addItemIntRecord NuGet50 NuGet50 10 257.64 ns 6.461 ns 1.000 ns 2.11 0.01 3 0.0584 - - 370 B
addItemIntRefRecord After After 10 147.27 ns 8.818 ns 2.290 ns 1.00 0.00 1 0.0308 - - 194 B
addItemIntRefRecord Main50 Main50 10 178.74 ns 4.237 ns 0.656 ns 1.21 0.02 2 0.0322 - - 202 B
addItemIntRefRecord NuGet50 NuGet50 10 295.57 ns 4.790 ns 0.741 ns 2.00 0.04 3 0.0313 - - 202 B
addItemIntLikeNonGenCmp After After 10 108.42 ns 1.574 ns 0.244 ns 1.00 0.00 1 0.0441 - - 278 B
addItemIntLikeNonGenCmp Main50 Main50 10 184.77 ns 3.463 ns 0.899 ns 1.71 0.00 2 0.0584 - - 370 B
addItemIntLikeNonGenCmp NuGet50 NuGet50 10 273.93 ns 4.158 ns 1.080 ns 2.53 0.01 3 0.0577 - - 370 B
addItemRefLikeNonGenCmp After After 10 167.32 ns 2.057 ns 0.534 ns 1.00 0.00 1 0.0308 - - 194 B
addItemRefLikeNonGenCmp Main50 Main50 10 199.51 ns 4.683 ns 0.725 ns 1.19 0.01 2 0.0318 - - 202 B
addItemRefLikeNonGenCmp NuGet50 NuGet50 10 320.73 ns 5.032 ns 1.307 ns 1.92 0.01 3 0.0321 - - 202 B
removeItemInt After After 10 11.87 ns 0.668 ns 0.173 ns 1.00 0.00 1 0.0056 - - 35 B
removeItemInt Main50 Main50 10 13.39 ns 0.242 ns 0.063 ns 1.13 0.02 2 0.0070 - - 44 B
removeItemInt NuGet50 NuGet50 10 16.93 ns 0.890 ns 0.231 ns 1.43 0.04 3 0.0070 - - 44 B
removeItemIntLike After After 10 11.88 ns 0.189 ns 0.049 ns 1.00 0.00 1 0.0056 - - 35 B
removeItemIntLike Main50 Main50 10 15.17 ns 0.241 ns 0.063 ns 1.28 0.01 2 0.0069 - - 44 B
removeItemIntLike NuGet50 NuGet50 10 18.37 ns 0.556 ns 0.144 ns 1.55 0.01 3 0.0070 - - 44 B
removeItemString After After 10 12.20 ns 0.206 ns 0.053 ns 1.00 0.00 1 0.0056 - - 35 B
removeItemString Main50 Main50 10 14.81 ns 0.308 ns 0.080 ns 1.21 0.01 2 0.0070 - - 44 B
removeItemString NuGet50 NuGet50 10 21.20 ns 0.403 ns 0.105 ns 1.74 0.01 3 0.0070 - - 44 B
removeItemRefLike After After 10 12.17 ns 0.302 ns 0.078 ns 1.00 0.00 1 0.0056 - - 35 B
removeItemRefLike Main50 Main50 10 14.27 ns 0.567 ns 0.147 ns 1.17 0.02 2 0.0070 - - 44 B
removeItemRefLike NuGet50 NuGet50 10 20.95 ns 0.278 ns 0.072 ns 1.72 0.01 3 0.0070 - - 44 B
removeItemIntRecord After After 10 13.16 ns 0.193 ns 0.050 ns 1.00 0.00 1 0.0056 - - 35 B
removeItemIntRecord Main50 Main50 10 15.32 ns 0.558 ns 0.145 ns 1.16 0.01 2 0.0070 - - 44 B
removeItemIntRecord NuGet50 NuGet50 10 19.50 ns 0.592 ns 0.154 ns 1.48 0.02 3 0.0070 - - 44 B
removeItemIntRefRecord After After 10 12.07 ns 0.155 ns 0.040 ns 1.00 0.00 1 0.0056 - - 35 B
removeItemIntRefRecord Main50 Main50 10 14.46 ns 0.470 ns 0.122 ns 1.20 0.01 2 0.0070 - - 44 B
removeItemIntRefRecord NuGet50 NuGet50 10 20.97 ns 0.257 ns 0.067 ns 1.74 0.00 3 0.0070 - - 44 B
removeItemIntLikeNonGenCmp After After 10 12.08 ns 0.939 ns 0.244 ns 1.00 0.00 1 0.0056 - - 35 B
removeItemIntLikeNonGenCmp Main50 Main50 10 15.07 ns 0.670 ns 0.174 ns 1.25 0.04 2 0.0070 - - 44 B
removeItemIntLikeNonGenCmp NuGet50 NuGet50 10 18.33 ns 1.013 ns 0.157 ns 1.52 0.03 3 0.0069 - - 44 B
removeItemRefLikeNonGenCmp After After 10 12.13 ns 0.455 ns 0.118 ns 1.00 0.00 1 0.0056 - - 35 B
removeItemRefLikeNonGenCmp Main50 Main50 10 14.47 ns 0.613 ns 0.159 ns 1.19 0.02 2 0.0070 - - 44 B
removeItemRefLikeNonGenCmp NuGet50 NuGet50 10 20.94 ns 0.375 ns 0.058 ns 1.72 0.01 3 0.0069 - - 44 B
getItemInt After After 100 18.97 ns 1.405 ns 0.365 ns 1.00 0.00 1 - - - -
getItemInt Main50 Main50 100 31.79 ns 1.192 ns 0.310 ns 1.68 0.04 2 - - - -
getItemInt NuGet50 NuGet50 100 72.33 ns 0.624 ns 0.097 ns 3.81 0.08 3 - - - -
getItemIntLike After After 100 66.84 ns 1.111 ns 0.172 ns 1.00 0.00 1 - - - -
getItemIntLike Main50 Main50 100 246.56 ns 3.648 ns 0.947 ns 3.69 0.02 2 0.0524 - - 331 B
getItemIntLike NuGet50 NuGet50 100 269.86 ns 9.044 ns 2.349 ns 4.02 0.02 3 0.0526 - - 331 B
getItemString After After 100 53.10 ns 0.925 ns 0.240 ns 1.00 0.00 2 - - - -
getItemString Main50 Main50 100 46.17 ns 1.272 ns 0.197 ns 0.87 0.00 1 - - - -
getItemString NuGet50 NuGet50 100 94.81 ns 5.599 ns 1.454 ns 1.79 0.03 3 - - - -
getItemRefLike After After 100 144.73 ns 1.508 ns 0.392 ns 1.00 0.00 1 - - - -
getItemRefLike Main50 Main50 100 228.45 ns 1.093 ns 0.284 ns 1.58 0.00 2 - - - -
getItemRefLike NuGet50 NuGet50 100 275.51 ns 16.036 ns 4.165 ns 1.90 0.03 3 - - - -
getItemIntRecord After After 100 112.28 ns 0.595 ns 0.155 ns 1.00 0.00 1 - - - -
getItemIntRecord Main50 Main50 100 221.25 ns 6.780 ns 1.049 ns 1.97 0.01 2 0.0519 - - 331 B
getItemIntRecord NuGet50 NuGet50 100 253.14 ns 1.861 ns 0.288 ns 2.25 0.00 3 0.0520 - - 331 B
getItemIntRefRecord After After 100 148.41 ns 6.694 ns 1.738 ns 1.00 0.00 1 - - - -
getItemIntRefRecord Main50 Main50 100 198.03 ns 5.669 ns 1.472 ns 1.33 0.01 2 - - - -
getItemIntRefRecord NuGet50 NuGet50 100 230.73 ns 8.749 ns 2.272 ns 1.55 0.01 3 - - - -
getItemIntLikeNonGenCmp After After 100 99.52 ns 2.670 ns 0.693 ns 1.00 0.00 1 0.0259 - - 166 B
getItemIntLikeNonGenCmp Main50 Main50 100 230.76 ns 5.653 ns 0.875 ns 2.32 0.02 2 0.0528 - - 331 B
getItemIntLikeNonGenCmp NuGet50 NuGet50 100 267.13 ns 8.118 ns 2.108 ns 2.68 0.02 3 0.0520 - - 331 B
getItemRefLikeNonGenCmp After After 100 184.42 ns 11.382 ns 2.956 ns 1.00 0.00 1 - - - -
getItemRefLikeNonGenCmp Main50 Main50 100 228.82 ns 2.496 ns 0.648 ns 1.24 0.02 2 - - - -
getItemRefLikeNonGenCmp NuGet50 NuGet50 100 269.54 ns 2.950 ns 0.457 ns 1.46 0.03 3 - - - -
containsKeyInt After After 100 20.13 ns 0.737 ns 0.191 ns 1.00 0.00 1 - - - -
containsKeyInt Main50 Main50 100 26.04 ns 1.071 ns 0.278 ns 1.29 0.01 2 - - - -
containsKeyInt NuGet50 NuGet50 100 68.27 ns 1.918 ns 0.498 ns 3.39 0.05 3 - - - -
containsKeyIntLike After After 100 57.12 ns 1.138 ns 0.296 ns 1.00 0.00 1 - - - -
containsKeyIntLike Main50 Main50 100 239.60 ns 4.630 ns 0.717 ns 4.19 0.03 2 0.0526 - - 331 B
containsKeyIntLike NuGet50 NuGet50 100 273.49 ns 4.715 ns 1.224 ns 4.79 0.04 3 0.0515 - - 331 B
containsKeyString After After 100 52.79 ns 3.496 ns 0.541 ns 1.00 0.00 2 - - - -
containsKeyString Main50 Main50 100 41.96 ns 1.304 ns 0.202 ns 0.79 0.01 1 - - - -
containsKeyString NuGet50 NuGet50 100 85.71 ns 2.955 ns 0.767 ns 1.62 0.01 3 - - - -
containsKeyRefLike After After 100 148.24 ns 1.592 ns 0.246 ns 1.00 0.00 1 - - - -
containsKeyRefLike Main50 Main50 100 234.13 ns 3.836 ns 0.594 ns 1.58 0.00 2 - - - -
containsKeyRefLike NuGet50 NuGet50 100 277.66 ns 7.306 ns 1.131 ns 1.87 0.01 3 - - - -
containsKeyIntRecord After After 100 100.83 ns 3.616 ns 0.939 ns 1.00 0.00 1 - - - -
containsKeyIntRecord Main50 Main50 100 229.00 ns 5.064 ns 1.315 ns 2.27 0.02 2 0.0520 - - 331 B
containsKeyIntRecord NuGet50 NuGet50 100 253.70 ns 16.919 ns 4.394 ns 2.52 0.06 3 0.0524 - - 331 B
containsKeyIntRefRecord After After 100 152.22 ns 3.240 ns 0.841 ns 1.00 0.00 1 - - - -
containsKeyIntRefRecord Main50 Main50 100 199.06 ns 1.979 ns 0.514 ns 1.31 0.01 2 - - - -
containsKeyIntRefRecord NuGet50 NuGet50 100 238.39 ns 6.600 ns 1.714 ns 1.57 0.01 3 - - - -
containsKeyIntLikeNonGenCmp After After 100 92.18 ns 2.185 ns 0.567 ns 1.00 0.00 1 0.0259 - - 166 B
containsKeyIntLikeNonGenCmp Main50 Main50 100 227.40 ns 2.670 ns 0.413 ns 2.47 0.02 2 0.0521 - - 331 B
containsKeyIntLikeNonGenCmp NuGet50 NuGet50 100 266.46 ns 7.369 ns 1.140 ns 2.89 0.02 3 0.0525 - - 331 B
containsKeyRefLikeNonGenCmp After After 100 189.16 ns 8.976 ns 1.389 ns 1.00 0.00 1 - - - -
containsKeyRefLikeNonGenCmp Main50 Main50 100 228.42 ns 4.952 ns 1.286 ns 1.21 0.01 2 - - - -
containsKeyRefLikeNonGenCmp NuGet50 NuGet50 100 277.98 ns 17.608 ns 2.725 ns 1.47 0.02 3 - - - -
itemCountInt After After 100 220.44 ns 10.117 ns 1.566 ns 1.00 0.00 2 - - - -
itemCountInt Main50 Main50 100 199.87 ns 13.089 ns 3.399 ns 0.91 0.02 1 - - - -
itemCountInt NuGet50 NuGet50 100 642.65 ns 33.597 ns 8.725 ns 2.92 0.05 3 - - - -
itemCountIntLike After After 100 219.28 ns 5.408 ns 1.404 ns 1.00 0.00 2 - - - -
itemCountIntLike Main50 Main50 100 199.12 ns 8.339 ns 2.166 ns 0.91 0.01 1 - - - -
itemCountIntLike NuGet50 NuGet50 100 638.60 ns 21.622 ns 5.615 ns 2.91 0.02 3 - - - -
itemCountString After After 100 210.41 ns 22.729 ns 5.903 ns 1.00 0.00 1 - - - -
itemCountString Main50 Main50 100 270.53 ns 20.309 ns 5.274 ns 1.29 0.04 2 - - - -
itemCountString NuGet50 NuGet50 100 808.91 ns 37.733 ns 9.799 ns 3.85 0.08 3 - - - -
itemCountRefLike After After 100 236.75 ns 44.960 ns 11.676 ns 1.00 0.00 1 - - - -
itemCountRefLike Main50 Main50 100 302.45 ns 37.958 ns 5.874 ns 1.30 0.03 2 - - - -
itemCountRefLike NuGet50 NuGet50 100 767.23 ns 78.398 ns 20.360 ns 3.24 0.13 3 - - - -
itemCountIntRecord After After 100 224.46 ns 9.359 ns 2.430 ns 1.00 0.00 2 - - - -
itemCountIntRecord Main50 Main50 100 199.73 ns 12.131 ns 1.877 ns 0.89 0.02 1 - - - -
itemCountIntRecord NuGet50 NuGet50 100 643.28 ns 24.220 ns 3.748 ns 2.87 0.03 3 - - - -
itemCountIntRefRecord After After 100 226.96 ns 56.269 ns 8.708 ns 1.00 0.00 1 - - - -
itemCountIntRefRecord Main50 Main50 100 290.03 ns 17.004 ns 2.631 ns 1.28 0.05 2 - - - -
itemCountIntRefRecord NuGet50 NuGet50 100 765.14 ns 24.892 ns 6.464 ns 3.38 0.12 3 - - - -
itemCountIntLikeNonGenCmp After After 100 222.73 ns 10.156 ns 2.637 ns 1.00 0.00 2 - - - -
itemCountIntLikeNonGenCmp Main50 Main50 100 198.28 ns 7.031 ns 1.826 ns 0.89 0.01 1 - - - -
itemCountIntLikeNonGenCmp NuGet50 NuGet50 100 643.04 ns 13.256 ns 3.442 ns 2.89 0.04 3 - - - -
itemCountRefLikeNonGenCmp After After 100 225.86 ns 10.792 ns 1.670 ns 1.00 0.00 1 - - - -
itemCountRefLikeNonGenCmp Main50 Main50 100 293.91 ns 27.602 ns 7.168 ns 1.31 0.03 2 - - - -
itemCountRefLikeNonGenCmp NuGet50 NuGet50 100 750.74 ns 6.918 ns 1.071 ns 3.32 0.03 3 - - - -
iterForeachInt After After 100 3,184.55 ns 15.290 ns 2.366 ns 1.00 0.00 2 1.0300 - - 6520 B
iterForeachInt Main50 Main50 100 3,143.18 ns 52.629 ns 8.144 ns 0.99 0.00 1 1.0388 - - 6520 B
iterForeachInt NuGet50 NuGet50 100 3,799.58 ns 416.457 ns 108.153 ns 1.18 0.03 3 0.9650 - - 6120 B
iterForeachIntLike After After 100 3,150.37 ns 57.264 ns 14.871 ns 1.00 0.00 1 1.0321 - - 6520 B
iterForeachIntLike Main50 Main50 100 3,234.08 ns 270.363 ns 41.839 ns 1.03 0.01 1 1.0338 - - 6520 B
iterForeachIntLike NuGet50 NuGet50 100 3,735.78 ns 54.658 ns 8.458 ns 1.19 0.01 2 1.0304 - - 6520 B
iterForeachString After After 100 3,967.17 ns 77.569 ns 20.145 ns 1.00 0.00 1 1.0543 - - 6648 B
iterForeachString Main50 Main50 100 4,008.56 ns 298.115 ns 77.420 ns 1.01 0.02 1 1.0440 - - 6648 B
iterForeachString NuGet50 NuGet50 100 5,457.60 ns 145.137 ns 37.692 ns 1.38 0.01 2 1.0326 - - 6648 B
iterForeachRefLike After After 100 3,832.74 ns 30.726 ns 7.980 ns 1.00 0.00 1 1.0365 - - 6520 B
iterForeachRefLike Main50 Main50 100 3,848.77 ns 69.727 ns 10.790 ns 1.00 0.00 1 1.0331 - - 6520 B
iterForeachRefLike NuGet50 NuGet50 100 5,614.49 ns 355.689 ns 92.371 ns 1.46 0.02 2 1.0326 - - 6520 B
iterForeachIntRecord After After 100 3,159.59 ns 56.652 ns 14.712 ns 1.00 0.00 1 1.0267 - - 6520 B
iterForeachIntRecord Main50 Main50 100 3,151.96 ns 240.842 ns 62.546 ns 1.00 0.02 1 1.0310 - - 6520 B
iterForeachIntRecord NuGet50 NuGet50 100 3,918.45 ns 35.634 ns 9.254 ns 1.24 0.00 2 1.0210 - - 6520 B
iterForeachIntRefRecord After After 100 3,779.77 ns 14.858 ns 2.299 ns 1.00 0.00 1 1.0376 - - 6520 B
iterForeachIntRefRecord Main50 Main50 100 4,095.19 ns 774.857 ns 201.228 ns 1.07 0.06 2 1.0285 - - 6520 B
iterForeachIntRefRecord NuGet50 NuGet50 100 5,452.34 ns 92.963 ns 14.386 ns 1.44 0.00 3 1.0326 - - 6520 B
iterForeachIntLikeNonGenCmp After After 100 3,141.00 ns 48.912 ns 12.702 ns 1.00 0.00 1 1.0243 - - 6520 B
iterForeachIntLikeNonGenCmp Main50 Main50 100 3,148.50 ns 77.225 ns 11.951 ns 1.00 0.00 1 1.0300 - - 6520 B
iterForeachIntLikeNonGenCmp NuGet50 NuGet50 100 3,727.12 ns 67.235 ns 10.405 ns 1.19 0.00 2 1.0346 - - 6520 B
iterForeachRefLikeNonGenCmp After After 100 3,776.05 ns 100.223 ns 26.028 ns 1.00 0.00 1 1.0323 - - 6520 B
iterForeachRefLikeNonGenCmp Main50 Main50 100 3,895.12 ns 79.005 ns 20.517 ns 1.03 0.01 2 1.0230 - - 6520 B
iterForeachRefLikeNonGenCmp NuGet50 NuGet50 100 5,475.10 ns 126.439 ns 32.836 ns 1.45 0.01 3 1.0308 - - 6520 B
addItemInt After After 100 149.46 ns 1.576 ns 0.409 ns 1.00 0.00 1 0.0566 - - 357 B
addItemInt Main50 Main50 100 158.51 ns 1.524 ns 0.236 ns 1.06 0.00 2 0.0578 - - 366 B
addItemInt NuGet50 NuGet50 100 357.40 ns 3.389 ns 0.524 ns 2.39 0.00 3 0.0568 - - 361 B
addItemIntLike After After 100 184.74 ns 3.445 ns 0.533 ns 1.00 0.00 1 0.0563 - - 357 B
addItemIntLike Main50 Main50 100 375.63 ns 12.012 ns 1.859 ns 2.03 0.01 2 0.1103 - - 697 B
addItemIntLike NuGet50 NuGet50 100 588.16 ns 3.557 ns 0.550 ns 3.18 0.01 3 0.1088 - - 697 B
addItemString After After 100 176.26 ns 3.440 ns 0.893 ns 1.00 0.00 1 0.0468 - - 298 B
addItemString Main50 Main50 100 173.71 ns 15.523 ns 4.031 ns 0.99 0.02 1 0.0487 - - 306 B
addItemString NuGet50 NuGet50 100 376.89 ns 5.216 ns 0.807 ns 2.14 0.01 2 0.0471 - - 306 B
addItemRefLike After After 100 296.47 ns 2.760 ns 0.717 ns 1.00 0.00 1 0.0560 - - 357 B
addItemRefLike Main50 Main50 100 384.48 ns 16.062 ns 2.486 ns 1.30 0.01 2 0.0574 - - 366 B
addItemRefLike NuGet50 NuGet50 100 678.90 ns 10.881 ns 1.684 ns 2.29 0.01 3 0.0576 - - 366 B
addItemIntRecord After After 100 248.07 ns 4.178 ns 1.085 ns 1.00 0.00 1 0.0557 - - 357 B
addItemIntRecord Main50 Main50 100 366.16 ns 28.587 ns 7.424 ns 1.48 0.03 2 0.1102 - - 697 B
addItemIntRecord NuGet50 NuGet50 100 560.83 ns 10.335 ns 1.599 ns 2.26 0.01 3 0.1092 - - 697 B
addItemIntRefRecord After After 100 296.26 ns 6.037 ns 1.568 ns 1.00 0.00 1 0.0557 - - 357 B
addItemIntRefRecord Main50 Main50 100 359.93 ns 39.231 ns 10.188 ns 1.21 0.03 2 0.0581 - - 366 B
addItemIntRefRecord NuGet50 NuGet50 100 626.88 ns 8.513 ns 1.317 ns 2.12 0.01 3 0.0559 - - 366 B
addItemIntLikeNonGenCmp After After 100 222.56 ns 7.935 ns 2.061 ns 1.00 0.00 1 0.0829 - - 522 B
addItemIntLikeNonGenCmp Main50 Main50 100 369.14 ns 4.631 ns 0.717 ns 1.66 0.02 2 0.1104 - - 697 B
addItemIntLikeNonGenCmp NuGet50 NuGet50 100 592.62 ns 6.368 ns 1.654 ns 2.66 0.03 3 0.1095 - - 697 B
addItemRefLikeNonGenCmp After After 100 338.14 ns 5.822 ns 1.512 ns 1.00 0.00 1 0.0556 - - 357 B
addItemRefLikeNonGenCmp Main50 Main50 100 381.96 ns 6.078 ns 0.941 ns 1.13 0.01 2 0.0569 - - 366 B
addItemRefLikeNonGenCmp NuGet50 NuGet50 100 689.68 ns 10.552 ns 2.740 ns 2.04 0.01 3 0.0549 - - 366 B
removeItemInt After After 100 100.60 ns 1.375 ns 0.357 ns 1.00 0.00 1 0.0392 - - 246 B
removeItemInt Main50 Main50 100 107.81 ns 8.196 ns 2.129 ns 1.07 0.02 2 0.0406 - - 255 B
removeItemInt NuGet50 NuGet50 100 253.37 ns 2.330 ns 0.361 ns 2.52 0.01 3 0.0401 - - 255 B
removeItemIntLike After After 100 124.58 ns 1.924 ns 0.500 ns 1.00 0.00 1 0.0389 - - 246 B
removeItemIntLike Main50 Main50 100 240.29 ns 19.539 ns 5.074 ns 1.93 0.04 2 0.0741 - - 466 B
removeItemIntLike NuGet50 NuGet50 100 388.22 ns 3.008 ns 0.781 ns 3.12 0.01 3 0.0737 - - 466 B
removeItemString After After 100 202.76 ns 4.735 ns 1.230 ns 1.00 0.00 2 0.0493 - - 314 B
removeItemString Main50 Main50 100 194.10 ns 7.282 ns 1.127 ns 0.96 0.01 1 0.0511 - - 322 B
removeItemString NuGet50 NuGet50 100 465.08 ns 4.439 ns 1.153 ns 2.29 0.01 3 0.0491 - - 322 B
removeItemRefLike After After 100 185.09 ns 5.629 ns 0.871 ns 1.00 0.00 1 0.0388 - - 246 B
removeItemRefLike Main50 Main50 100 251.99 ns 29.504 ns 7.662 ns 1.37 0.05 2 0.0404 - - 255 B
removeItemRefLike NuGet50 NuGet50 100 484.94 ns 2.478 ns 0.644 ns 2.62 0.01 3 0.0387 - - 255 B
removeItemIntRecord After After 100 148.08 ns 1.551 ns 0.403 ns 1.00 0.00 1 0.0393 - - 246 B
removeItemIntRecord Main50 Main50 100 224.98 ns 10.822 ns 2.810 ns 1.52 0.02 2 0.0743 - - 466 B
removeItemIntRecord NuGet50 NuGet50 100 387.87 ns 2.351 ns 0.611 ns 2.62 0.01 3 0.0739 - - 466 B
removeItemIntRefRecord After After 100 192.79 ns 2.909 ns 0.450 ns 1.00 0.00 1 0.0389 - - 246 B
removeItemIntRefRecord Main50 Main50 100 223.71 ns 5.286 ns 1.373 ns 1.16 0.01 2 0.0399 - - 255 B
removeItemIntRefRecord NuGet50 NuGet50 100 466.15 ns 3.277 ns 0.507 ns 2.42 0.00 3 0.0395 - - 255 B
removeItemIntLikeNonGenCmp After After 100 135.38 ns 1.913 ns 0.497 ns 1.00 0.00 1 0.0561 - - 352 B
removeItemIntLikeNonGenCmp Main50 Main50 100 240.62 ns 7.711 ns 1.193 ns 1.78 0.01 2 0.0742 - - 466 B
removeItemIntLikeNonGenCmp NuGet50 NuGet50 100 398.46 ns 4.807 ns 1.248 ns 2.94 0.01 3 0.0736 - - 466 B
removeItemRefLikeNonGenCmp After After 100 210.35 ns 3.156 ns 0.488 ns 1.00 0.00 1 0.0392 - - 246 B
removeItemRefLikeNonGenCmp Main50 Main50 100 246.89 ns 19.505 ns 5.065 ns 1.16 0.02 2 0.0401 - - 255 B
removeItemRefLikeNonGenCmp NuGet50 NuGet50 100 487.36 ns 6.175 ns 1.604 ns 2.32 0.01 3 0.0389 - - 255 B
getItemInt After After 1000 25.02 ns 0.827 ns 0.128 ns 1.00 0.00 1 - - - -
getItemInt Main50 Main50 1000 48.14 ns 0.952 ns 0.247 ns 1.92 0.01 2 - - - -
getItemInt NuGet50 NuGet50 1000 108.20 ns 0.849 ns 0.221 ns 4.32 0.02 3 - - - -
getItemIntLike After After 1000 94.32 ns 1.025 ns 0.159 ns 1.00 0.00 1 - - - -
getItemIntLike Main50 Main50 1000 352.89 ns 12.728 ns 3.306 ns 3.73 0.04 2 0.0770 - - 490 B
getItemIntLike NuGet50 NuGet50 1000 388.50 ns 4.462 ns 1.159 ns 4.12 0.01 3 0.0776 - - 490 B
getItemString After After 1000 96.66 ns 3.952 ns 0.612 ns 1.00 0.00 2 - - - -
getItemString Main50 Main50 1000 77.31 ns 0.980 ns 0.152 ns 0.80 0.00 1 - - - -
getItemString NuGet50 NuGet50 1000 156.42 ns 4.430 ns 1.151 ns 1.61 0.02 3 - - - -
getItemRefLike After After 1000 202.58 ns 2.227 ns 0.578 ns 1.00 0.00 1 - - - -
getItemRefLike Main50 Main50 1000 319.66 ns 5.877 ns 0.910 ns 1.58 0.00 2 - - - -
getItemRefLike NuGet50 NuGet50 1000 384.77 ns 9.908 ns 1.533 ns 1.90 0.01 3 - - - -
getItemIntRecord After After 1000 157.66 ns 0.780 ns 0.202 ns 1.00 0.00 1 - - - -
getItemIntRecord Main50 Main50 1000 314.41 ns 7.215 ns 1.874 ns 1.99 0.01 2 0.0770 - - 490 B
getItemIntRecord NuGet50 NuGet50 1000 356.50 ns 8.239 ns 2.140 ns 2.26 0.01 3 0.0775 - - 490 B
getItemIntRefRecord After After 1000 205.85 ns 1.482 ns 0.385 ns 1.00 0.00 1 - - - -
getItemIntRefRecord Main50 Main50 1000 264.93 ns 4.938 ns 1.282 ns 1.29 0.01 2 - - - -
getItemIntRefRecord NuGet50 NuGet50 1000 320.31 ns 7.575 ns 1.967 ns 1.56 0.01 3 - - - -
getItemIntLikeNonGenCmp After After 1000 149.52 ns 12.115 ns 1.875 ns 1.00 0.00 1 0.0389 - - 245 B
getItemIntLikeNonGenCmp Main50 Main50 1000 329.73 ns 3.041 ns 0.471 ns 2.21 0.03 2 0.0773 - - 490 B
getItemIntLikeNonGenCmp NuGet50 NuGet50 1000 389.06 ns 25.240 ns 6.555 ns 2.61 0.03 3 0.0762 - - 490 B
getItemRefLikeNonGenCmp After After 1000 250.07 ns 4.115 ns 0.637 ns 1.00 0.00 1 - - - -
getItemRefLikeNonGenCmp Main50 Main50 1000 321.05 ns 1.900 ns 0.493 ns 1.28 0.01 2 - - - -
getItemRefLikeNonGenCmp NuGet50 NuGet50 1000 386.16 ns 8.447 ns 2.194 ns 1.54 0.01 3 - - - -
containsKeyInt After After 1000 28.67 ns 0.341 ns 0.089 ns 1.00 0.00 1 - - - -
containsKeyInt Main50 Main50 1000 37.03 ns 1.107 ns 0.287 ns 1.29 0.01 2 - - - -
containsKeyInt NuGet50 NuGet50 1000 101.60 ns 1.478 ns 0.384 ns 3.54 0.01 3 - - - -
containsKeyIntLike After After 1000 94.45 ns 1.779 ns 0.462 ns 1.00 0.00 1 - - - -
containsKeyIntLike Main50 Main50 1000 341.01 ns 19.770 ns 5.134 ns 3.61 0.05 2 0.0775 - - 490 B
containsKeyIntLike NuGet50 NuGet50 1000 385.47 ns 4.900 ns 1.272 ns 4.08 0.03 3 0.0767 - - 490 B
containsKeyString After After 1000 96.93 ns 4.180 ns 0.647 ns 1.00 0.00 2 - - - -
containsKeyString Main50 Main50 1000 71.39 ns 2.019 ns 0.524 ns 0.73 0.01 1 - - - -
containsKeyString NuGet50 NuGet50 1000 146.28 ns 6.038 ns 0.934 ns 1.51 0.02 3 - - - -
containsKeyRefLike After After 1000 205.47 ns 10.856 ns 2.819 ns 1.00 0.00 1 - - - -
containsKeyRefLike Main50 Main50 1000 322.46 ns 1.045 ns 0.272 ns 1.57 0.02 2 - - - -
containsKeyRefLike NuGet50 NuGet50 1000 394.52 ns 2.167 ns 0.335 ns 1.92 0.03 3 - - - -
containsKeyIntRecord After After 1000 156.54 ns 1.374 ns 0.357 ns 1.00 0.00 1 - - - -
containsKeyIntRecord Main50 Main50 1000 307.61 ns 14.769 ns 2.286 ns 1.96 0.01 2 0.0780 - - 490 B
containsKeyIntRecord NuGet50 NuGet50 1000 355.10 ns 21.796 ns 5.660 ns 2.27 0.04 3 0.0778 - - 490 B
containsKeyIntRefRecord After After 1000 211.84 ns 3.127 ns 0.484 ns 1.00 0.00 1 - - - -
containsKeyIntRefRecord Main50 Main50 1000 267.75 ns 1.141 ns 0.177 ns 1.26 0.00 2 - - - -
containsKeyIntRefRecord NuGet50 NuGet50 1000 332.18 ns 1.878 ns 0.291 ns 1.57 0.00 3 - - - -
containsKeyIntLikeNonGenCmp After After 1000 147.87 ns 2.210 ns 0.574 ns 1.00 0.00 1 0.0384 - - 245 B
containsKeyIntLikeNonGenCmp Main50 Main50 1000 326.15 ns 4.386 ns 0.679 ns 2.21 0.01 2 0.0780 - - 490 B
containsKeyIntLikeNonGenCmp NuGet50 NuGet50 1000 386.89 ns 21.193 ns 5.504 ns 2.62 0.04 3 0.0766 - - 490 B
containsKeyRefLikeNonGenCmp After After 1000 249.97 ns 3.375 ns 0.876 ns 1.00 0.00 1 - - - -
containsKeyRefLikeNonGenCmp Main50 Main50 1000 319.27 ns 8.171 ns 1.264 ns 1.28 0.01 2 - - - -
containsKeyRefLikeNonGenCmp NuGet50 NuGet50 1000 395.52 ns 11.528 ns 1.784 ns 1.58 0.01 3 - - - -
itemCountInt After After 1000 3,055.82 ns 201.240 ns 52.261 ns 1.00 0.00 2 - - - -
itemCountInt Main50 Main50 1000 2,826.45 ns 235.528 ns 61.166 ns 0.93 0.02 1 - - - -
itemCountInt NuGet50 NuGet50 1000 7,030.40 ns 217.806 ns 56.563 ns 2.30 0.05 3 - - - -
itemCountIntLike After After 1000 3,061.21 ns 239.546 ns 62.209 ns 1.00 0.00 2 - - - -
itemCountIntLike Main50 Main50 1000 2,779.95 ns 76.816 ns 19.949 ns 0.91 0.01 1 - - - -
itemCountIntLike NuGet50 NuGet50 1000 7,142.48 ns 108.106 ns 28.075 ns 2.33 0.04 3 - - - -
itemCountString After After 1000 3,406.13 ns 236.256 ns 36.561 ns 1.00 0.00 1 - - - -
itemCountString Main50 Main50 1000 3,566.58 ns 113.958 ns 29.595 ns 1.05 0.00 2 - - - -
itemCountString NuGet50 NuGet50 1000 8,920.93 ns 116.982 ns 18.103 ns 2.62 0.03 3 - - - -
itemCountRefLike After After 1000 3,298.94 ns 170.981 ns 26.459 ns 1.00 0.00 1 - - - -
itemCountRefLike Main50 Main50 1000 3,479.42 ns 179.309 ns 46.566 ns 1.05 0.01 2 - - - -
itemCountRefLike NuGet50 NuGet50 1000 8,546.53 ns 216.172 ns 33.453 ns 2.59 0.03 3 - - - -
itemCountIntRecord After After 1000 3,034.17 ns 101.451 ns 26.347 ns 1.00 0.00 2 - - - -
itemCountIntRecord Main50 Main50 1000 2,846.96 ns 272.815 ns 70.849 ns 0.94 0.02 1 - - - -
itemCountIntRecord NuGet50 NuGet50 1000 7,088.36 ns 189.757 ns 49.279 ns 2.34 0.02 3 - - - -
itemCountIntRefRecord After After 1000 3,351.18 ns 172.547 ns 44.810 ns 1.00 0.00 1 - - - -
itemCountIntRefRecord Main50 Main50 1000 3,491.27 ns 41.517 ns 6.425 ns 1.04 0.02 2 - - - -
itemCountIntRefRecord NuGet50 NuGet50 1000 8,556.55 ns 66.093 ns 17.164 ns 2.55 0.04 3 - - - -
itemCountIntLikeNonGenCmp After After 1000 3,075.82 ns 103.606 ns 26.906 ns 1.00 0.00 2 - - - -
itemCountIntLikeNonGenCmp Main50 Main50 1000 2,830.64 ns 195.015 ns 50.645 ns 0.92 0.02 1 - - - -
itemCountIntLikeNonGenCmp NuGet50 NuGet50 1000 7,074.52 ns 226.681 ns 58.868 ns 2.30 0.03 3 - - - -
itemCountRefLikeNonGenCmp After After 1000 3,258.14 ns 160.712 ns 41.736 ns 1.00 0.00 1 - - - -
itemCountRefLikeNonGenCmp Main50 Main50 1000 3,512.67 ns 88.312 ns 22.934 ns 1.08 0.01 2 - - - -
itemCountRefLikeNonGenCmp NuGet50 NuGet50 1000 8,525.15 ns 76.360 ns 19.830 ns 2.62 0.03 3 - - - -
iterForeachInt After After 1000 33,235.90 ns 1,256.411 ns 326.286 ns 1.00 0.00 1 10.1974 - - 64120 B
iterForeachInt Main50 Main50 1000 33,450.22 ns 846.144 ns 219.741 ns 1.01 0.01 1 10.1396 - - 64120 B
iterForeachInt NuGet50 NuGet50 1000 39,009.83 ns 601.700 ns 93.114 ns 1.18 0.01 2 9.5405 - - 60120 B
iterForeachIntLike After After 1000 33,313.42 ns 680.245 ns 176.657 ns 1.00 0.00 1 10.2212 - - 64120 B
iterForeachIntLike Main50 Main50 1000 33,004.49 ns 405.091 ns 105.201 ns 0.99 0.01 1 10.1127 - - 64120 B
iterForeachIntLike NuGet50 NuGet50 1000 39,379.16 ns 1,016.077 ns 263.872 ns 1.18 0.01 2 10.1881 - - 64120 B
iterForeachString After After 1000 42,224.61 ns 829.107 ns 215.317 ns 1.00 0.00 1 10.9536 - - 68728 B
iterForeachString Main50 Main50 1000 42,272.99 ns 1,669.605 ns 433.591 ns 1.00 0.01 1 10.8696 - - 68728 B
iterForeachString NuGet50 NuGet50 1000 57,869.96 ns 478.920 ns 124.374 ns 1.37 0.01 2 10.6635 - - 68728 B
iterForeachRefLike After After 1000 41,250.21 ns 3,390.599 ns 880.528 ns 1.00 0.00 1 10.1010 - - 64120 B
iterForeachRefLike Main50 Main50 1000 40,761.32 ns 904.343 ns 139.948 ns 1.00 0.01 1 10.0334 - - 64120 B
iterForeachRefLike NuGet50 NuGet50 1000 57,284.45 ns 772.117 ns 119.486 ns 1.40 0.02 2 10.0446 - - 64120 B
iterForeachIntRecord After After 1000 33,679.78 ns 1,635.842 ns 424.823 ns 1.00 0.00 1 10.0860 - - 64120 B
iterForeachIntRecord Main50 Main50 1000 33,052.35 ns 567.626 ns 147.411 ns 0.98 0.01 1 10.1127 - - 64120 B
iterForeachIntRecord NuGet50 NuGet50 1000 41,185.73 ns 1,424.841 ns 370.027 ns 1.22 0.02 2 10.0410 - - 64120 B
iterForeachIntRefRecord After After 1000 41,717.10 ns 885.258 ns 229.899 ns 1.00 0.00 2 10.0599 - - 64120 B
iterForeachIntRefRecord Main50 Main50 1000 39,929.41 ns 2,542.898 ns 393.516 ns 0.96 0.01 1 10.1837 - - 64120 B
iterForeachIntRefRecord NuGet50 NuGet50 1000 56,990.85 ns 1,988.155 ns 516.318 ns 1.37 0.01 3 10.0897 - - 64120 B
iterForeachIntLikeNonGenCmp After After 1000 33,414.51 ns 2,153.555 ns 559.271 ns 1.00 0.00 1 10.1396 - - 64120 B
iterForeachIntLikeNonGenCmp Main50 Main50 1000 33,154.32 ns 823.731 ns 127.473 ns 0.99 0.02 1 10.1127 - - 64120 B
iterForeachIntLikeNonGenCmp NuGet50 NuGet50 1000 39,843.78 ns 2,070.478 ns 537.697 ns 1.19 0.03 2 10.2201 - - 64120 B
iterForeachRefLikeNonGenCmp After After 1000 40,992.92 ns 1,572.246 ns 408.307 ns 1.00 0.00 1 10.2163 - - 64120 B
iterForeachRefLikeNonGenCmp Main50 Main50 1000 40,656.75 ns 3,498.869 ns 541.454 ns 0.99 0.01 1 10.1513 - - 64120 B
iterForeachRefLikeNonGenCmp NuGet50 NuGet50 1000 57,462.64 ns 2,372.846 ns 616.221 ns 1.40 0.02 2 10.0806 - - 64120 B
addItemInt After After 1000 241.67 ns 13.794 ns 3.582 ns 1.00 0.00 1 0.0816 - - 515 B
addItemInt Main50 Main50 1000 238.33 ns 31.165 ns 8.093 ns 0.99 0.04 1 0.0829 - - 524 B
addItemInt NuGet50 NuGet50 1000 542.05 ns 2.944 ns 0.765 ns 2.24 0.03 2 0.0813 - - 519 B
addItemIntLike After After 1000 287.60 ns 10.849 ns 2.817 ns 1.00 0.00 1 0.0816 - - 515 B
addItemIntLike Main50 Main50 1000 576.99 ns 79.313 ns 20.597 ns 2.01 0.08 2 0.1598 - - 1014 B
addItemIntLike NuGet50 NuGet50 1000 871.13 ns 15.566 ns 4.043 ns 3.03 0.03 3 0.1572 - - 1014 B
addItemString After After 1000 311.91 ns 28.343 ns 4.386 ns 1.00 0.00 2 0.0731 - - 466 B
addItemString Main50 Main50 1000 291.01 ns 12.160 ns 3.158 ns 0.94 0.02 1 0.0743 - - 474 B
addItemString NuGet50 NuGet50 1000 677.33 ns 2.210 ns 0.342 ns 2.17 0.03 3 0.0744 - - 474 B
addItemRefLike After After 1000 444.25 ns 18.302 ns 2.832 ns 1.00 0.00 1 0.0805 - - 515 B
addItemRefLike Main50 Main50 1000 580.43 ns 63.247 ns 9.788 ns 1.31 0.02 2 0.0810 - - 524 B
addItemRefLike NuGet50 NuGet50 1000 993.81 ns 3.105 ns 0.806 ns 2.24 0.01 3 0.0799 - - 524 B
addItemIntRecord After After 1000 380.90 ns 8.203 ns 1.269 ns 1.00 0.00 1 0.0815 - - 515 B
addItemIntRecord Main50 Main50 1000 524.61 ns 7.189 ns 1.112 ns 1.38 0.00 2 0.1591 - - 1014 B
addItemIntRecord NuGet50 NuGet50 1000 810.34 ns 10.017 ns 2.602 ns 2.13 0.00 3 0.1576 - - 1014 B
addItemIntRefRecord After After 1000 443.09 ns 19.383 ns 5.034 ns 1.00 0.00 1 0.0813 - - 515 B
addItemIntRefRecord Main50 Main50 1000 516.02 ns 14.630 ns 2.264 ns 1.17 0.02 2 0.0818 - - 524 B
addItemIntRefRecord NuGet50 NuGet50 1000 928.03 ns 8.637 ns 2.243 ns 2.09 0.02 3 0.0833 - - 524 B
addItemIntLikeNonGenCmp After After 1000 339.04 ns 2.564 ns 0.397 ns 1.00 0.00 1 0.1207 - - 760 B
addItemIntLikeNonGenCmp Main50 Main50 1000 554.66 ns 15.236 ns 2.358 ns 1.64 0.01 2 0.1613 - - 1014 B
addItemIntLikeNonGenCmp NuGet50 NuGet50 1000 882.71 ns 30.659 ns 7.962 ns 2.61 0.02 3 0.1580 - - 1014 B
addItemRefLikeNonGenCmp After After 1000 493.60 ns 4.568 ns 1.186 ns 1.00 0.00 1 0.0816 - - 515 B
addItemRefLikeNonGenCmp Main50 Main50 1000 553.96 ns 24.781 ns 6.435 ns 1.12 0.01 2 0.0821 - - 524 B
addItemRefLikeNonGenCmp NuGet50 NuGet50 1000 985.67 ns 15.301 ns 2.368 ns 2.00 0.01 3 0.0788 - - 524 B
removeItemInt After After 1000 165.01 ns 2.059 ns 0.319 ns 1.00 0.00 1 0.0643 - - 405 B
removeItemInt Main50 Main50 1000 176.17 ns 18.137 ns 4.710 ns 1.06 0.03 2 0.0658 - - 414 B
removeItemInt NuGet50 NuGet50 1000 441.60 ns 4.653 ns 1.208 ns 2.68 0.01 3 0.0639 - - 414 B
removeItemIntLike After After 1000 206.84 ns 5.278 ns 0.817 ns 1.00 0.00 1 0.0638 - - 405 B
removeItemIntLike Main50 Main50 1000 406.19 ns 29.419 ns 7.640 ns 1.96 0.04 2 0.1231 - - 783 B
removeItemIntLike NuGet50 NuGet50 1000 683.79 ns 10.607 ns 2.754 ns 3.31 0.02 3 0.1230 - - 783 B
removeItemString After After 1000 350.06 ns 5.199 ns 1.350 ns 1.00 0.00 1 0.0802 - - 510 B
removeItemString Main50 Main50 1000 334.93 ns 42.534 ns 11.046 ns 0.96 0.03 1 0.0819 - - 519 B
removeItemString NuGet50 NuGet50 1000 832.71 ns 22.998 ns 5.973 ns 2.38 0.01 2 0.0826 - - 519 B
removeItemRefLike After After 1000 343.39 ns 3.726 ns 0.968 ns 1.00 0.00 1 0.0638 - - 405 B
removeItemRefLike Main50 Main50 1000 418.47 ns 6.834 ns 1.775 ns 1.22 0.01 2 0.0648 - - 414 B
removeItemRefLike NuGet50 NuGet50 1000 807.87 ns 10.423 ns 2.707 ns 2.35 0.00 3 0.0649 - - 414 B
removeItemIntRecord After After 1000 267.43 ns 2.223 ns 0.577 ns 1.00 0.00 1 0.0637 - - 405 B
removeItemIntRecord Main50 Main50 1000 379.65 ns 4.758 ns 1.236 ns 1.42 0.00 2 0.1239 - - 783 B
removeItemIntRecord NuGet50 NuGet50 1000 662.82 ns 7.469 ns 1.156 ns 2.48 0.01 3 0.1233 - - 783 B
removeItemIntRefRecord After After 1000 338.94 ns 4.317 ns 0.668 ns 1.00 0.00 1 0.0644 - - 405 B
removeItemIntRefRecord Main50 Main50 1000 399.10 ns 27.237 ns 7.073 ns 1.18 0.02 2 0.0655 - - 414 B
removeItemIntRefRecord NuGet50 NuGet50 1000 788.90 ns 36.366 ns 9.444 ns 2.33 0.03 3 0.0658 - - 414 B
removeItemIntLikeNonGenCmp After After 1000 229.83 ns 3.315 ns 0.513 ns 1.00 0.00 1 0.0935 - - 590 B
removeItemIntLikeNonGenCmp Main50 Main50 1000 403.62 ns 10.840 ns 1.678 ns 1.76 0.01 2 0.1228 - - 783 B
removeItemIntLikeNonGenCmp NuGet50 NuGet50 1000 680.05 ns 20.804 ns 5.403 ns 2.96 0.03 3 0.1242 - - 783 B
removeItemRefLikeNonGenCmp After After 1000 377.34 ns 4.709 ns 1.223 ns 1.00 0.00 1 0.0627 - - 405 B
removeItemRefLikeNonGenCmp Main50 Main50 1000 424.20 ns 7.660 ns 1.185 ns 1.12 0.01 2 0.0650 - - 414 B
removeItemRefLikeNonGenCmp NuGet50 NuGet50 1000 804.00 ns 8.058 ns 2.093 ns 2.13 0.01 3 0.0642 - - 414 B

Inline primitive comparison, keep the rest the same. See Comparison/cmp comments on how and why this works.
Arrays and structural comparison may cause problems

Maybe should just copy the snippet from dotnet#9348
…ilable

It's unambiguous. If it does something different than other ways to compare then it's very weird.

F# records implement IComparable<T> that works as expected.
buybackoff added a commit to buybackoff/fsharp that referenced this pull request Jan 10, 2021
@cartermp
Copy link
Contributor

Hmmmm. The regression for reflikes in your testing is troublesome. I can't speak towards overall usage, but within the compiler we definitely make heavy use of reference types and this would negatively affect that.

@buybackoff
Copy link
Contributor Author

Hmmmm. The regression for reflikes in your testing is troublesome. I can't speak towards overall usage, but within the compiler we definitely make heavy use of reference types and this would negatively affect that.

Yes, when I was writing "<5% mostly edge cases" of course I was biased towards my own usage patterns...

Overall, these things look too complicated. I opened the draft PRs mostly for CI and to show the magnitude of possible improvements. I'm glad that I was able to split the whole Map/Set story into independent steps. If you close these 2 comparer PRs I'm fine with it. A was aware of the comparer inefficiency for a long time. But I'm rather out of the loop these days and when I've learned all the complexity and history of the comparison vs Comparer<T>.Default issue I realized it's too much to push forward with this. It's a much bigger issue than just Map/Set.

@cartermp
Copy link
Contributor

Okay, makes sense. Thanks for the explanation! And for all of the enhancement so far :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants