Skip to content

[stdlib] Rewriting native hashed collection indices (rebased) #5291

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

Merged
merged 24 commits into from
Nov 4, 2016

Conversation

Gankra
Copy link
Contributor

@Gankra Gankra commented Oct 14, 2016

This is a rebase of #3046. The majority of the work here is @austinzheng's, and can be found in the first commit. However the codebase had changed enough that the patch had to be significantly modified. I'm mostly relying on the test suite to verify that there weren't errors in resolving all the conflicts.

Changes:
- Native dictionary and set indices no longer hold references to storage
- Cocoa-based dictionary and set indices no longer hold references to storage
- Removed double indirection trick from hashed collections
- Rewrote storage types to reflect simpler model
- Updated unit tests

As a consequence of removing the double indirection, Dictionary -> NSDictionary now always requires an allocation for a wrapper class. This means that if you bridge a Dictionary multiple times, the resultant NSDictionaries will not be referentially identical. I briefly investigated trying to restore the previous behaviour; or at least perform the optimizations that Array does to make the verbatim-bridgeable case free.

Discussion with @dabrahams lead to the conclusion that restoring the previous behaviour isn't necessary or even strictly desirable. In particular, the old behaviour could lead to the bridged buffer being kept alive much longer than necessary. This design ensures those are cleaned up as soon as possible.

My own research into adopting Array's optimization appears to be infeasible, as _NativeDictionaryStorage already inherits from ManagedBuffer, and so can't inherit from _NSDictionaryCore as well (right?).

Still, it should be noted that this will almost certainly lead to regressions in bridging performance. At least in micro-benchmarks.

It should also be noted that this redesign is necessary for soundness, as the double-indirection design is unsound for multi-threading (as discussed in SE-0065: https://github.com/apple/swift-evolution/blob/master/proposals/0065-collections-move-indices.md).

TODO before merge:

  • re-instate empty-collection-singleton
  • fix comparison change
  • evaluate benches
  • fix documentation

@Gankra
Copy link
Contributor Author

Gankra commented Oct 14, 2016

(repeating this comment from the other PR)

The only outstanding problem is that the new bridging implementation seems to be breaking equality comparisons for [AnyHashable: Any] when bridged to NSDictionary. In particular, this assert is now failing: https://github.com/apple/swift/blob/c3b7709a7c4789f1ad7249d357f69509fb8be731/test/stdlib/TestUserInfo.swift#L101

I'm guessing this is because this kind of Dictionary doesn't provide its own equality comparison, so it's falling back to some object identity stuff, which is no longer holding? Not sure what guarantees we're providing here, or how to proceed. Any idea what the right solution is?

CC @moiseev @dabrahams

(I'm submitting the PR now to parallelize review+discussion, since this issue shouldn't affect much)

@Gankra
Copy link
Contributor Author

Gankra commented Oct 14, 2016

@swift-ci please smoke test

@Gankra
Copy link
Contributor Author

Gankra commented Oct 14, 2016

@swift-ci please benchmark

@Gankra
Copy link
Contributor Author

Gankra commented Oct 14, 2016

Oh interesting. The new source-stability machinery caught that we removed Index.successor(). I genuinely have no idea how we can source-stability bridge that.

Copy link
Contributor

@dabrahams dabrahams left a comment

Choose a reason for hiding this comment

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

Is this equality "dubious," or simply no longer something we can keep providing once bridging is made eager?

@Gankra
Copy link
Contributor Author

Gankra commented Oct 14, 2016

@dabrahams to be honest, I don't even understand how it was passing before. Why would two independently constructed empty dictionaries have the same address?

Edit for future readers: the answer is that we had some sort of empty singleton optimization here, and I missed that it got removed by this patch. Must fix!

@Gankra
Copy link
Contributor Author

Gankra commented Oct 14, 2016

Wait are you referring to the comment I made above, or the last commit I pushed?

@swift-ci
Copy link
Contributor

Build comment file:

Optimized (O)

Regression (13)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ObjectiveCBridgeToNSDictionary 15989 63540 +297.4% 0.25x
ObjectiveCBridgeToNSSet 15792 41979 +165.8% 0.38x
ObjectiveCBridgeFromNSSetAnyObjectForced 4605 5549 +20.5% 0.83x
ObjectiveCBridgeFromNSDictionaryAnyObjectForced 5350 6390 +19.4% 0.84x
CaptureProp 4057 4563 +12.5% 0.89x
StringHasSuffix 709 791 +11.6% 0.90x
Calculator 31 34 +9.7% 0.91x
ObjectiveCBridgeStubNSDateRefAccess 308 338 +9.7% 0.91x
Hanoi 3165 3446 +8.9% 0.92x
ObjectiveCBridgeStubFromNSDate 3407 3684 +8.1% 0.92x
ObjectiveCBridgeFromNSDictionaryAnyObject 201665 215833 +7.0% 0.93x
Dictionary3OfObjects 856 920 +7.5% 0.93x
Phonebook 7067 7625 +7.9% 0.93x

Improvement (18)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
SetUnion_OfObjects 6598 6230 -5.6% 1.06x
SetExclusiveOr_OfObjects 7855 7255 -7.6% 1.08x
DictionaryRemoveOfObjects 19648 17965 -8.6% 1.09x
ObjectiveCBridgeStubToNSDateRef 3755 3411 -9.2% 1.10x
SetIntersect_OfObjects 2273 1977 -13.0% 1.15x
ObjectiveCBridgeFromNSSetAnyObject 261775 221762 -15.3% 1.18x
SetExclusiveOr 2645 2188 -17.3% 1.21x
RGBHistogram 2816 2334 -17.1% 1.21x
TwoSum 1585 1284 -19.0% 1.23x
NSDictionaryCastToSwift 6905 4847 -29.8% 1.42x
Histogram 656 454 -30.8% 1.44x
SetIsSubsetOf_OfObjects 524 360 -31.3% 1.46x
DictionarySwap 628 406 -35.4% 1.55x
SetUnion 3039 1792 -41.0% 1.70x
SetIsSubsetOf 509 285 -44.0% 1.79x
DictionaryRemove 4578 2526 -44.8% 1.81x
DictionaryLiteral 2750 1344 -51.1% 2.05x
SetIntersect 1084 337 -68.9% 3.22x

No Changes (105)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
StaticArray 2777 2643 -4.8% 1.05x(?)
Dictionary2 2038 1945 -4.6% 1.05x(?)
Dictionary 742 708 -4.6% 1.05x
StringHasPrefixUnicode 14418 13777 -4.5% 1.05x
ObjectiveCBridgeStubToNSDate 14353 13754 -4.2% 1.04x(?)
Prims 714 690 -3.4% 1.03x(?)
DictionarySwapOfObjects 6753 6573 -2.7% 1.03x
SortStringsUnicode 8320 8111 -2.5% 1.03x
StackPromo 21527 21188 -1.6% 1.02x(?)
ObjectiveCBridgeStubFromNSDateRef 3709 3626 -2.2% 1.02x
ObjectiveCBridgeToNSArray 30308 29725 -1.9% 1.02x(?)
Dictionary2OfObjects 3384 3320 -1.9% 1.02x
ObjectiveCBridgeToNSString 1072 1066 -0.6% 1.01x(?)
StringInterpolation 10880 10727 -1.4% 1.01x(?)
ErrorHandling 2914 2891 -0.8% 1.01x(?)
ArrayOfRef 3543 3515 -0.8% 1.01x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToString 119695 118388 -1.1% 1.01x(?)
ArraySubscript 1419 1422 +0.2% 1.00x(?)
MonteCarloPi 45209 45135 -0.2% 1.00x(?)
PopFrontArray 1111 1116 +0.5% 1.00x(?)
RecursiveOwnedParameter 1937 1934 -0.1% 1.00x(?)
ObjectiveCBridgeStubToNSString 1280 1280 +0.0% 1.00x
AnyHashableWithAClass 63128 62941 -0.3% 1.00x(?)
ClassArrayGetter 12 12 +0.0% 1.00x
Array2D 2028 2029 +0.1% 1.00x(?)
ArrayOfGenericPOD 220 220 +0.0% 1.00x
StringWithCString 155027 155199 +0.1% 1.00x(?)
ObjectiveCBridgeFromNSArrayAnyObjectForced 6023 6016 -0.1% 1.00x(?)
SortLettersInPlace 973 974 +0.1% 1.00x(?)
StrComplexWalk 2890 2877 -0.5% 1.00x(?)
ByteSwap 0 0 +0.0% 1.00x
SuperChars 211420 211362 -0.0% 1.00x(?)
XorLoop 380 380 +0.0% 1.00x
Integrate 239 238 -0.4% 1.00x
ObjectiveCBridgeStubFromNSStringRef 128 128 +0.0% 1.00x
ProtocolDispatch 3040 3040 +0.0% 1.00x
ObjectAllocation 153 153 +0.0% 1.00x
TypeFlood 0 0 +0.0% 1.00x
ArrayLiteral 1178 1179 +0.1% 1.00x(?)
ProtocolDispatch2 159 159 +0.0% 1.00x
HashTest 1749 1742 -0.4% 1.00x(?)
ObjectiveCBridgeStubDateMutation 273 273 +0.0% 1.00x
DictionaryOfObjects 2284 2295 +0.5% 1.00x(?)
PopFrontArrayGeneric 1117 1117 +0.0% 1.00x
PopFrontUnsafePointer 9176 9200 +0.3% 1.00x(?)
StringEqualPointerComparison 7323 7355 +0.4% 1.00x(?)
PolymorphicCalls 22 22 +0.0% 1.00x
ObjectiveCBridgeStubToNSStringRef 116 116 +0.0% 1.00x
MapReduce 342 342 +0.0% 1.00x
UTF8Decode 288 289 +0.3% 1.00x
NopDeinit 36662 36661 -0.0% 1.00x(?)
ObjectiveCBridgeStubToArrayOfNSString 29428 29402 -0.1% 1.00x(?)
GlobalClass 0 0 +0.0% 1.00x
StringBuilder 1318 1318 +0.0% 1.00x
ArrayInClass 62 62 +0.0% 1.00x
ArrayOfGenericRef 3571 3579 +0.2% 1.00x(?)
ObjectiveCBridgeFromNSString 1804 1810 +0.3% 1.00x(?)
ObjectiveCBridgeStubDateAccess 182 182 +0.0% 1.00x
Sim2DArray 277 277 +0.0% 1.00x
StringHasSuffixUnicode 63350 63147 -0.3% 1.00x(?)
Walsh 320 320 +0.0% 1.00x
ArrayAppend 774 774 +0.0% 1.00x
LinkedList 7257 7260 +0.0% 1.00x(?)
NSStringConversion 817 814 -0.4% 1.00x(?)
ArrayValueProp4 6 6 +0.0% 1.00x
ArrayOfPOD 182 182 +0.0% 1.00x
Chars 630 630 +0.0% 1.00x
DeadArray 185 185 +0.0% 1.00x
ArrayValueProp2 6 6 +0.0% 1.00x
BitCount 1 1 +0.0% 1.00x
AngryPhonebook 2819 2825 +0.2% 1.00x(?)
StringWalk 5883 5883 +0.0% 1.00x
ArrayValueProp 6 6 +0.0% 1.00x
RC4 165 165 +0.0% 1.00x
Memset 235 236 +0.4% 1.00x
ArrayAppendReserved 536 536 +0.0% 1.00x
ArrayValueProp3 6 6 +0.0% 1.00x
135 3188720 3224071 +1.1% 0.99x
ObjectiveCBridgeFromNSStringForced 2647 2675 +1.1% 0.99x(?)
ObjectiveCBridgeStubURLAppendPathRef 231853 235124 +1.4% 0.99x(?)
NSError 324 326 +0.6% 0.99x(?)
ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced 135323 136991 +1.2% 0.99x(?)
ObjectiveCBridgeFromNSArrayAnyObject 75571 76624 +1.4% 0.99x(?)
ObjectiveCBridgeStubDataAppend 2941 2958 +0.6% 0.99x(?)
MonteCarloE 10451 10530 +0.8% 0.99x(?)
SevenBoom 1337 1348 +0.8% 0.99x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToStringForced 90297 91421 +1.2% 0.99x(?)
ObjectiveCBridgeStubFromArrayOfNSString 58551 59118 +1.0% 0.99x(?)
ObjectiveCBridgeStubNSDateMutationRef 12323 12438 +0.9% 0.99x(?)
ObjectiveCBridgeStubNSDataAppend 2416 2434 +0.8% 0.99x(?)
DictionaryBridge 3782 3853 +1.9% 0.98x(?)
Join 459 467 +1.7% 0.98x(?)
IterateData 2539 2602 +2.5% 0.98x
ObjectiveCBridgeStubURLAppendPath 229623 234485 +2.1% 0.98x(?)
RGBHistogramOfObjects 21979 22337 +1.6% 0.98x(?)
ObjectiveCBridgeFromNSDictionaryAnyObjectToString 208742 215025 +3.0% 0.97x(?)
SortStrings 1771 1834 +3.6% 0.97x
ObjectiveCBridgeStubFromNSString 763 790 +3.5% 0.97x
Dictionary3 507 523 +3.2% 0.97x
RangeAssignment 274 286 +4.4% 0.96x(?)
ObjectiveCBridgeFromNSSetAnyObjectToStringForced 106263 110210 +3.7% 0.96x(?)
StringHasPrefix 608 639 +5.1% 0.95x
OpenClose 54 57 +5.6% 0.95x
ObjectiveCBridgeFromNSSetAnyObjectToString 142266 150535 +5.8% 0.95x(?)
StrToInt 5033 5294 +5.2% 0.95x
**Unoptimized (Onone)**

Regression (7)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ObjectiveCBridgeToNSDictionary 16517 64664 +291.5% 0.26x
ObjectiveCBridgeToNSSet 16153 42248 +161.6% 0.38x
ObjectiveCBridgeFromNSDictionaryAnyObjectForced 7784 8819 +13.3% 0.88x
ObjectiveCBridgeFromNSSetAnyObjectForced 7508 8573 +14.2% 0.88x
StrComplexWalk 7171 8072 +12.6% 0.89x
ArrayAppendReserved 3105 3324 +7.0% 0.93x
StringHasSuffix 1673 1779 +6.3% 0.94x

Improvement (15)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ProtocolDispatch 5776 5473 -5.2% 1.06x
Dictionary 2147 2026 -5.6% 1.06x
BitCount 102 96 -5.9% 1.06x
ObjectiveCBridgeStubDateMutation 486 456 -6.2% 1.07x
PopFrontUnsafePointer 259304 242903 -6.3% 1.07x
Calculator 1019 948 -7.0% 1.07x
Histogram 11877 10983 -7.5% 1.08x
DictionaryLiteral 16677 14953 -10.3% 1.12x
SetExclusiveOr 30412 26844 -11.7% 1.13x
RGBHistogram 44090 38351 -13.0% 1.15x
ObjectiveCBridgeFromNSSetAnyObject 272563 231447 -15.1% 1.18x
DictionarySwap 7521 6345 -15.6% 1.19x
TwoSum 6569 5519 -16.0% 1.19x
SetUnion 18528 14816 -20.0% 1.25x
NSDictionaryCastToSwift 8310 6328 -23.9% 1.31x

No Changes (114)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
SetIsSubsetOf_OfObjects 2214 2117 -4.4% 1.05x
RGBHistogramOfObjects 93412 89030 -4.7% 1.05x
SetIsSubsetOf 2449 2345 -4.2% 1.04x
CaptureProp 121156 118071 -2.5% 1.03x
Phonebook 63685 62086 -2.5% 1.03x(?)
Prims 13599 13371 -1.7% 1.02x
Dictionary2 4488 4381 -2.4% 1.02x
StringEqualPointerComparison 9887 9732 -1.6% 1.02x
SetExclusiveOr_OfObjects 46794 46060 -1.6% 1.02x
SetUnion_OfObjects 34380 33857 -1.5% 1.02x
DictionaryRemove 17392 17085 -1.8% 1.02x
ObjectiveCBridgeFromNSSetAnyObjectToStringForced 120658 118061 -2.1% 1.02x(?)
NSStringConversion 3023 2967 -1.9% 1.02x(?)
StringBuilder 2714 2666 -1.8% 1.02x(?)
StringWalk 21493 21098 -1.8% 1.02x
ObjectiveCBridgeToNSString 1111 1103 -0.7% 1.01x
ObjectiveCBridgeFromNSDictionaryAnyObjectToString 222523 219915 -1.2% 1.01x(?)
ObjectiveCBridgeStubFromNSDateRef 4101 4068 -0.8% 1.01x
RangeAssignment 27747 27566 -0.7% 1.01x(?)
SuperChars 264407 261897 -0.9% 1.01x(?)
StringInterpolation 15817 15648 -1.1% 1.01x
ObjectAllocation 562 556 -1.1% 1.01x(?)
StringHasSuffixUnicode 64928 64565 -0.6% 1.01x
AnyHashableWithAClass 78212 77492 -0.9% 1.01x
ObjectiveCBridgeStubURLAppendPathRef 241500 239732 -0.7% 1.01x(?)
PopFrontArrayGeneric 9711 9640 -0.7% 1.01x(?)
AngryPhonebook 2992 2970 -0.7% 1.01x(?)
Hanoi 20684 20421 -1.3% 1.01x
ObjectiveCBridgeStubURLAppendPath 235101 233225 -0.8% 1.01x(?)
SortStringsUnicode 9455 9361 -1.0% 1.01x
MonteCarloE 109384 108684 -0.6% 1.01x
Chars 5049 4997 -1.0% 1.01x
ArraySubscript 5616 5599 -0.3% 1.00x(?)
StackPromo 128119 128265 +0.1% 1.00x(?)
135 5574266 5560601 -0.2% 1.00x
RecursiveOwnedParameter 10923 10883 -0.4% 1.00x(?)
ObjectiveCBridgeStubToNSString 1335 1337 +0.1% 1.00x(?)
ClassArrayGetter 1267 1267 +0.0% 1.00x
Array2D 813177 811793 -0.2% 1.00x(?)
ArrayOfGenericPOD 3613 3597 -0.4% 1.00x(?)
StringWithCString 154737 154728 -0.0% 1.00x(?)
ObjectiveCBridgeFromNSStringForced 3081 3084 +0.1% 1.00x(?)
SortLettersInPlace 2571 2559 -0.5% 1.00x
ByteSwap 9 9 +0.0% 1.00x
XorLoop 19988 20011 +0.1% 1.00x(?)
Join 1464 1462 -0.1% 1.00x(?)
ObjectiveCBridgeStubFromNSString 833 830 -0.4% 1.00x(?)
StaticArray 34855 34883 +0.1% 1.00x(?)
ProtocolDispatch2 444 444 +0.0% 1.00x
HashTest 5398 5385 -0.2% 1.00x(?)
ErrorHandling 3805 3805 +0.0% 1.00x
NSError 679 677 -0.3% 1.00x(?)
ObjectiveCBridgeStubToNSDateRef 3357 3366 +0.3% 1.00x(?)
MapReduce 45097 45074 -0.1% 1.00x(?)
IterateData 10622 10638 +0.1% 1.00x(?)
UTF8Decode 43530 43580 +0.1% 1.00x(?)
SetIntersect 15256 15317 +0.4% 1.00x(?)
StrToInt 5787 5775 -0.2% 1.00x(?)
ArrayInClass 3956 3953 -0.1% 1.00x(?)
ArrayOfGenericRef 10055 10095 +0.4% 1.00x(?)
Sim2DArray 14575 14589 +0.1% 1.00x
MonteCarloPi 53712 53508 -0.4% 1.00x
RC4 9367 9370 +0.0% 1.00x(?)
Walsh 13181 13178 -0.0% 1.00x(?)
LinkedList 27666 27780 +0.4% 1.00x(?)
ArrayOfPOD 2329 2328 -0.0% 1.00x(?)
DeadArray 120969 120581 -0.3% 1.00x(?)
ObjectiveCBridgeStubNSDataAppend 2796 2803 +0.2% 1.00x(?)
ArrayLiteral 1245 1248 +0.2% 1.00x(?)
SevenBoom 1497 1493 -0.3% 1.00x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToStringForced 91841 92026 +0.2% 1.00x(?)
ArrayValueProp 2618 2616 -0.1% 1.00x(?)
ObjectiveCBridgeStubNSDateMutationRef 14702 14672 -0.2% 1.00x(?)
GlobalClass 0 0 +0.0% 1.00x
Memset 20650 20672 +0.1% 1.00x(?)
ArrayValueProp4 3022 3025 +0.1% 1.00x(?)
ArrayValueProp2 3135 3143 +0.3% 1.00x
ArrayValueProp3 3074 3079 +0.2% 1.00x(?)
PopFrontArray 24005 24164 +0.7% 0.99x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToString 120893 121997 +0.9% 0.99x(?)
SortStrings 2691 2716 +0.9% 0.99x
Integrate 366 368 +0.6% 0.99x(?)
ArrayOfRef 9344 9395 +0.6% 0.99x(?)
ObjectiveCBridgeToNSArray 30694 30925 +0.8% 0.99x(?)
DictionaryOfObjects 4890 4927 +0.8% 0.99x(?)
ObjectiveCBridgeStubToNSStringRef 155 156 +0.7% 0.99x(?)
OpenClose 457 461 +0.9% 0.99x(?)
ObjectiveCBridgeStubToArrayOfNSString 29814 29991 +0.6% 0.99x(?)
ObjectiveCBridgeFromNSString 5062 5126 +1.3% 0.99x
ObjectiveCBridgeStubFromArrayOfNSString 58698 59417 +1.2% 0.99x(?)
DictionarySwapOfObjects 21129 21458 +1.6% 0.98x(?)
ObjectiveCBridgeFromNSArrayAnyObjectForced 10088 10286 +2.0% 0.98x(?)
ObjectiveCBridgeStubFromNSStringRef 159 163 +2.5% 0.98x
TypeFlood 184 188 +2.2% 0.98x(?)
Dictionary3 1606 1643 +2.3% 0.98x
PolymorphicCalls 1128 1149 +1.9% 0.98x
NopDeinit 59685 61119 +2.4% 0.98x
ObjectiveCBridgeFromNSArrayAnyObject 78137 79360 +1.6% 0.98x(?)
ObjectiveCBridgeStubDataAppend 3299 3374 +2.3% 0.98x
StringHasPrefixUnicode 15376 15668 +1.9% 0.98x
Dictionary2OfObjects 6259 6383 +2.0% 0.98x(?)
DictionaryBridge 3876 4008 +3.4% 0.97x(?)
Dictionary3OfObjects 2264 2338 +3.3% 0.97x
SetIntersect_OfObjects 13921 14363 +3.2% 0.97x
ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced 140464 144250 +2.7% 0.97x(?)
ObjectiveCBridgeStubDateAccess 1064 1096 +3.0% 0.97x
ArrayAppend 3337 3433 +2.9% 0.97x(?)
StringHasPrefix 1561 1628 +4.3% 0.96x
ObjectiveCBridgeStubNSDateRefAccess 1201 1254 +4.4% 0.96x
ObjectiveCBridgeStubFromNSDate 3655 3791 +3.7% 0.96x
ObjectiveCBridgeFromNSDictionaryAnyObject 209708 221473 +5.6% 0.95x
ObjectiveCBridgeStubToNSDate 13780 14433 +4.7% 0.95x(?)
DictionaryRemoveOfObjects 46925 49569 +5.6% 0.95x(?)
ObjectiveCBridgeFromNSSetAnyObjectToString 157543 165467 +5.0% 0.95x
**Hardware Overview** Model Name: Mac mini Model Identifier: Macmini7,1 Processor Name: Intel Core i5 Processor Speed: 2.8 GHz Number of Processors: 1 Total Number of Cores: 2 L2 Cache (per Core): 256 KB L3 Cache: 3 MB Memory: 16 GB

@Gankra
Copy link
Contributor Author

Gankra commented Oct 14, 2016

These bench results seem pretty promising! Major regressions are in the expected place (bridging), and there's some big wins on a few native benchmarks!

@dabrahams
Copy link
Contributor

@bob-wilson Can someone on your team evaluate the performance results?

@Gankra
Copy link
Contributor Author

Gankra commented Oct 14, 2016

@jrose-apple I'm told you're the right person to ask about the correct behaviour for #5291 (comment)

@jrose-apple
Copy link
Contributor

I can't see how it ever could have been depending on object identity, but those two dictionaries definitely should remain equal. They're being created from the same source.

(It's possible, of course, that something is broken in either AnyHashable or our SwiftValue box, but then I'd expect it to be broken everywhere.)

@jckarter is the other person to ask here (especially without Dmitri). Any insights, Joe?

@jrose-apple
Copy link
Contributor

Ah, it could conceivably be fallout from @DougGregor's 25e00d7 as well.

@Gankra
Copy link
Contributor Author

Gankra commented Oct 15, 2016

The source-stability checker seems to be a false positive. .successor() is internal and unversioned. There shouldn't be any problem in removing it. How do we assert this to the system? (Just ignore it and manually merge when everything else is resolved?)

@Gankra
Copy link
Contributor Author

Gankra commented Oct 15, 2016

Reverting 25e00d7 doesn't seem to affect this test.

@jrose-apple how does the == implementation for NSDictionary even come into existence? What features of our implementation of NSDictionary are used to synthesize it? Genuinely can't find this information.

@jrose-apple
Copy link
Contributor

== for NSDictionary is provided by == for NSObject, which invokes isEqual(_:), which calls NSDictionary's override of that, which should check "contains same key-value pairs", which will call isEqual(_:) on keys and values. In this case the keys and values aren't Objective-C types, so I would expect them to be boxed, but it's also stretching beyond any areas I worked on. (Hence poking Joe.)

@Gankra
Copy link
Contributor Author

Gankra commented Oct 17, 2016

Ok yeah, that makes sense. I can see why this was working before and now it's broken.

Here's a minimal example demonstrating the problem:

import Foundation

struct MyType {
    var data: Int = 0
}

let dictOfEqs: [AnyHashable: Any] = [AnyHashable(1): 1]
let dictOfMisc: [AnyHashable: Any] = [AnyHashable(1): MyType()]
let dictOfDupe: [AnyHashable: Any] = [AnyHashable(1): MyType()]


let nsDictOfEqs1 = dictOfEqs as NSDictionary
let nsDictOfEqs2 = dictOfEqs as NSDictionary

print(nsDictOfEqs1 == nsDictOfEqs2)


let nsDictOfMisc1 = dictOfMisc as NSDictionary
let nsDictOfMisc2 = dictOfMisc as NSDictionary

print(nsDictOfMisc1 == nsDictOfMisc2)

let nsDictOfDupe = dictOfDupe as NSDictionary

print(nsDictOfMisc1 == nsDictOfDupe)

In Swift 3, this code prints:

true
true
false

With this patch, we get:

true
false
false

Why? Before, Dictionary cached the bridged buffer. So multiple bridgings stored the exact same elements if they had to be boxed. This is relevant for types which aren't natively comparable in Swift, because ObjC is forced to fall back to pointer identity. With a cached buffer, pointer identity holds for a dictionary that has been bridged multiple times!

But this is easily broken by making two Dictionaries which don't share the same cache, so this behaviour isn't especially reliable (hence why we always get false for the last case).

I would argue that while the Swift 3 behaviour is nice, it's arguably incorrect. Or at best, a foot gun. A model where as is understood as "pass by value", and therefore makes values with distinct identity is an easier to understand one.

Note that with this patch [AnyHashable: Any] is still well behaved if the Any'd type provides its own implementation of ==. This only breaks people relying on two non-comparable values having equal boxings.

@jrose-apple
Copy link
Contributor

Ah, that makes sense!

It's (unfortunately) a requirement of NSDictionary and NSArray that getting elements repeatedly results in the same pointer value, which is why that cache was there at all. But there's no reason to assume the cache would be shared between elements, and it's certainly a coincidence to be able to do it at all. The same would apply in Objective-C to value-like types that don't override -isEqual:, so this seems like reasonable behavior.

Just to check, if you make MyType Equatable, we get the first result, right?

@Gankra
Copy link
Contributor Author

Gankra commented Oct 17, 2016

Huh, seemingly no? I had assumed that Any was peeking into that. Need to investigate why ints are doing magic to Any...

@dabrahams
Copy link
Contributor

dabrahams commented Oct 17, 2016

I would argue that while the Swift 3 behaviour is nice, it's
arguably incorrect. Or at best, a foot gun.

No, this is exactly what I explained to you was happening with
_SwiftDeferredNSArray, just repeated for dictionaries. It would be
“nice” if we could get away with ignoring Cocoa programmers'
expectations that they get back the same objects (by identity) every
time they traverse an immutable collection, but, at least today, we
can't.

…or maybe I'm misunderstanding something.

@jckarter
Copy link
Contributor

I agree with @gankro. I think this behavior change is unavoidable with eager bridging. Since MyType isn't Equatable, there's no equality behavior we can offer in the bridged NSDictionary beyond object identity, and there's no way to preserve object identity if we build a fresh NSDictionary every time we bridge. If we cached the NSDictionary in the Dictionary value somehow, that's just pushing the problem around, since the Dictionary in Swift is a value type and we can't guarantee any instance-specific behavior.

@Gankra
Copy link
Contributor Author

Gankra commented Oct 17, 2016

@dabrahams _SwiftDeferredNSArray has the behaviour this patch is introducing.

import Foundation

struct MyType {
    var data: Int = 0
}

let arrayOfEqs: [Any] = [1]
let arrayOfMisc: [Any] = [MyType()]
let arrayOfDupe: [Any] = [MyType()]

let nsArrayOfEqs1 = arrayOfEqs as NSArray
let nsArrayOfEqs2 = arrayOfEqs as NSArray

print(nsArrayOfEqs1 == nsArrayOfEqs2)

let nsArrayOfMisc1 = arrayOfMisc as NSArray
let nsArrayOfMisc2 = arrayOfMisc as NSArray

print(nsArrayOfMisc1 == nsArrayOfMisc2)

let nsArrayOfDupe = arrayOfDupe as NSArray

print(nsArrayOfMisc1 == nsArrayOfDupe)

yields

true
false
false

We ensure that once bridged, an NSArray yields stable addresses. What NSDictionary is currently doing is ensuring that different NSDictionarys bridged from the same Dictionary have stable addresses.

(edited for some copy-paste errors)

@Gankra
Copy link
Contributor Author

Gankra commented Oct 17, 2016

Can anyone direct me to where the isEqual impl for Any/AnyObject is constructed? I can't figure out why Int's == impl is being passed through, but MyType's isn't.

@jckarter
Copy link
Contributor

@gankro Look at SwiftValue.mm. AFAICT, in your example MyType doesn't have an Equatable conformance, so the _SwiftValue bridging box ought to fall back to object identity. This is all behaving correctly AFAICT.

@Gankra
Copy link
Contributor Author

Gankra commented Oct 17, 2016

@jckarter yeah my posted examples don't, but adding the conformance doesn't seem to affect the behaviour of the code:

import Foundation

struct MyType: Equatable {
    var data: Int = 0

    static func ==(lhs: MyType, rhs: MyType) -> Bool {
        return lhs.data == rhs.data
    }
}



let dictOfEqs: [AnyHashable: Any] = [AnyHashable(1): 1]
let dictOfEqsDupe: [AnyHashable: Any] = [AnyHashable(1): 2]
let dictOfMisc: [AnyHashable: Any] = [AnyHashable(1): MyType()]
let dictOfDupe: [AnyHashable: Any] = [AnyHashable(1): MyType()]


let nsDictOfEqs1 = dictOfEqs as NSDictionary
let nsDictOfEqs2 = dictOfEqs as NSDictionary

print(nsDictOfEqs1 == nsDictOfEqs2)

let nsDictOfEqsDupe = dictOfEqsDupe as NSDictionary

print(nsDictOfEqs1 == nsDictOfEqsDupe)

let nsDictOfMisc1 = dictOfMisc as NSDictionary
let nsDictOfMisc2 = dictOfMisc as NSDictionary

print(nsDictOfMisc1 == nsDictOfMisc2)

let nsDictOfDupe = dictOfDupe as NSDictionary

print(nsDictOfMisc1 == nsDictOfDupe)

print("\narrays:")


let arrayOfEqs: [Any] = [1]
let arrayOfMisc: [Any] = [MyType()]
let arrayOfDupe: [Any] = [MyType()]

let nsArrayOfEqs1 = arrayOfEqs as NSArray
let nsArrayOfEqs2 = arrayOfEqs as NSArray

print(nsArrayOfEqs1 == nsArrayOfEqs2)

let nsArrayOfMisc1 = arrayOfMisc as NSArray
let nsArrayOfMisc2 = arrayOfMisc as NSArray

print(nsArrayOfMisc1 == nsArrayOfMisc2)

let nsArrayOfDupe = arrayOfDupe as NSArray

print(nsArrayOfMisc1 == nsArrayOfDupe)

before patch:

true
false
true
false

arrays:
true
false
false

after patch:

true
false
false
false

arrays:
true
false
false

@Gankra
Copy link
Contributor Author

Gankra commented Oct 17, 2016

@_@ the isEqual impl uses Hashable, not Equatable

@dabrahams
Copy link
Contributor

on Mon Oct 17 2016, Alexis Beingessner <notifications-AT-i.8713187.xyz> wrote:

We ensure that once bridged, an NSDictionary yields stable
addresses. What NSDictionary is currently doing is ensuring that
different NSDictionarys bridged from the same Dictionary have stable
addresses.

Oh! In that case, yeah, kill that behavior. Nobody asked for that
behavior AFAIK.

-Dave

@dabrahams
Copy link
Contributor

on Mon Oct 17 2016, Alexis Beingessner <notifications-AT-i.8713187.xyz> wrote:

@_@ the isEqual impl uses Hashable, not Equatable

Arguably we ought to have an AnyEquatable, too, but that's a separate
project.

-Dave

@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

@swift-ci Please smoke test

@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

@swift-ci please benchmark

@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

@dabrahams I believe I've addressed all of your comments

(also fixed a mem-safety bug, yay!)

@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

@swift-ci Please smoke test

Copy link
Contributor

@dabrahams dabrahams left a comment

Choose a reason for hiding this comment

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

What was happening before you did this?!

@dabrahams
Copy link
Contributor

on Thu Nov 03 2016, Alexis Beingessner <notifications-AT-i.8713187.xyz> wrote:

@dabrahams I believe I've addressed all of your comments

W00t! I trust that it's ready to go as soon as the tests pass; feel free
to merge then.

@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

@swift-ci please smoke test

@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

@swift-ci Please benchmark

@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

@swift-ci Please smoke test

@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

@swift-ci Please smoke test

1 similar comment
@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

@swift-ci Please smoke test

@swift-ci
Copy link
Contributor

swift-ci commented Nov 4, 2016

Build comment file:

Optimized (O)

Regression (5)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ObjectiveCBridgeToNSDictionary 16291 70358 +331.9% 0.23x
ObjectiveCBridgeToNSSet 15242 43852 +187.7% 0.35x
ObjectiveCBridgeFromNSDictionaryAnyObjectForced 5260 6454 +22.7% 0.81x
ObjectiveCBridgeFromNSSetAnyObjectForced 4556 5651 +24.0% 0.81x
ArraySubscript 1435 1525 +6.3% 0.94x

Improvement (20)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ObjectiveCBridgeStubFromNSDate 3644 3408 -6.5% 1.07x(?)
MapReduce 373 342 -8.3% 1.09x
StrToInt 5495 5057 -8.0% 1.09x
PopFrontArrayGeneric 1229 1119 -8.9% 1.10x(?)
DictionarySwapOfObjects 6753 6046 -10.5% 1.12x
OpenClose 59 51 -13.6% 1.16x
ProtocolDispatch2 187 160 -14.4% 1.17x
CaptureProp 4882 4136 -15.3% 1.18x
TwoSum 1582 1341 -15.2% 1.18x
RGBHistogram 2826 2296 -18.8% 1.23x
SetUnion 2984 2185 -26.8% 1.37x
NSDictionaryCastToSwift 6913 5001 -27.7% 1.38x
SetIntersect_OfObjects 2272 1494 -34.2% 1.52x
DictionarySwap 632 410 -35.1% 1.54x
SetIsSubsetOf_OfObjects 523 310 -40.7% 1.69x
DictionaryRemove 4604 2492 -45.9% 1.85x
DictionaryLiteral 2730 1291 -52.7% 2.11x
SetIsSubsetOf 508 237 -53.4% 2.14x
Histogram 656 288 -56.1% 2.28x
SetIntersect 1084 308 -71.6% 3.52x

No Changes (122)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
PolymorphicCalls 22 21 -4.5% 1.05x
SetExclusiveOr_OfObjects 7947 7533 -5.2% 1.05x
NopDeinit 38085 36627 -3.8% 1.04x
SetUnion_OfObjects 6630 6355 -4.2% 1.04x
SortStrings 1837 1784 -2.9% 1.03x
ObjectiveCBridgeFromNSString 1844 1784 -3.2% 1.03x(?)
ObjectiveCBridgeStubToNSDate 13840 13389 -3.3% 1.03x(?)
AnyHashableWithAClass 66545 64661 -2.8% 1.03x
Calculator 36 35 -2.8% 1.03x
StringHasSuffix 800 780 -2.5% 1.03x(?)
ErrorHandling 2934 2877 -1.9% 1.02x(?)
HashTest 1752 1710 -2.4% 1.02x
SetExclusiveOr 2628 2589 -1.5% 1.02x(?)
ArrayInClass 63 62 -1.6% 1.02x(?)
RGBHistogramOfObjects 22008 21554 -2.1% 1.02x
DeadArray 185 182 -1.6% 1.02x
StackPromo 21618 21489 -0.6% 1.01x(?)
PopFrontArray 1128 1120 -0.7% 1.01x(?)
SuperChars 213338 212245 -0.5% 1.01x(?)
ObjectiveCBridgeStubFromNSStringRef 131 130 -0.8% 1.01x(?)
StringHasSuffixUnicode 63105 62636 -0.7% 1.01x
ArrayOfRef 3544 3526 -0.5% 1.01x(?)
ObjectiveCBridgeToNSArray 30450 30145 -1.0% 1.01x(?)
PopFrontUnsafePointer 9175 9124 -0.6% 1.01x(?)
StringEqualPointerComparison 7361 7302 -0.8% 1.01x(?)
ObjectiveCBridgeStubURLAppendPath 231609 229097 -1.1% 1.01x(?)
SortStringsUnicode 8335 8221 -1.4% 1.01x
Dictionary 740 734 -0.8% 1.01x
ObjectiveCBridgeStubDataAppend 2948 2931 -0.6% 1.01x(?)
ArrayOfGenericRef 3611 3580 -0.9% 1.01x(?)
MonteCarloE 10501 10430 -0.7% 1.01x(?)
Walsh 312 310 -0.6% 1.01x(?)
StringHasPrefixUnicode 13705 13541 -1.2% 1.01x
LinkedList 7268 7226 -0.6% 1.01x(?)
Chars 630 625 -0.8% 1.01x
ObjectiveCBridgeStubNSDateMutationRef 12365 12270 -0.8% 1.01x(?)
ObjectiveCBridgeToNSString 1071 1074 +0.3% 1.00x(?)
MonteCarloPi 45008 45000 -0.0% 1.00x(?)
RecursiveOwnedParameter 1933 1934 +0.1% 1.00x(?)
ObjectiveCBridgeStubToNSString 1281 1278 -0.2% 1.00x(?)
ClassArrayGetter 12 12 +0.0% 1.00x
Array2D 2029 2027 -0.1% 1.00x(?)
ObjectiveCBridgeStubFromNSDateRef 3712 3708 -0.1% 1.00x(?)
StringWithCString 154915 154981 +0.0% 1.00x(?)
ObjectiveCBridgeFromNSStringForced 2670 2660 -0.4% 1.00x(?)
Prims 738 735 -0.4% 1.00x(?)
SortLettersInPlace 975 974 -0.1% 1.00x(?)
StringHasPrefix 732 731 -0.1% 1.00x(?)
ByteSwap 0 0 +0.0% 1.00x
ArrayAppendGenericStructs 1233 1232 -0.1% 1.00x(?)
XorLoop 380 380 +0.0% 1.00x
ObserverClosure 1956 1964 +0.4% 1.00x(?)
Integrate 239 240 +0.4% 1.00x(?)
ArrayAppendStrings 12108 12123 +0.1% 1.00x(?)
ObjectiveCBridgeStubFromNSString 761 764 +0.4% 1.00x(?)
StaticArray 2737 2746 +0.3% 1.00x(?)
ProtocolDispatch 3040 3041 +0.0% 1.00x(?)
TypeFlood 0 0 +0.0% 1.00x
Dictionary2 2061 2058 -0.1% 1.00x(?)
ObserverUnappliedMethod 2380 2376 -0.2% 1.00x(?)
ObjectiveCBridgeStubURLAppendPathRef 230842 230887 +0.0% 1.00x(?)
ObjectiveCBridgeStubDateMutation 273 273 +0.0% 1.00x
NSError 325 325 +0.0% 1.00x
ObjectiveCBridgeStubToNSDateRef 3274 3280 +0.2% 1.00x(?)
ArrayAppendReserved 536 536 +0.0% 1.00x
ObjectiveCBridgeStubToNSStringRef 116 116 +0.0% 1.00x
ArrayAppendOptionals 1233 1230 -0.2% 1.00x(?)
ArrayOfGenericPOD 220 220 +0.0% 1.00x
DictionaryRemoveOfObjects 19727 19720 -0.0% 1.00x(?)
UTF8Decode 288 288 +0.0% 1.00x
ObjectiveCBridgeStubToArrayOfNSString 29347 29341 -0.0% 1.00x(?)
ObjectiveCBridgeFromNSArrayAnyObject 75660 75950 +0.4% 1.00x(?)
ObjectiveCBridgeStubNSDateRefAccess 308 308 +0.0% 1.00x
StringBuilder 1311 1317 +0.5% 1.00x(?)
ObjectiveCBridgeStubDateAccess 182 182 +0.0% 1.00x
Sim2DArray 277 277 +0.0% 1.00x
ArrayAppendRepeatCol 643 643 +0.0% 1.00x
RC4 165 165 +0.0% 1.00x
ArrayAppend 775 775 +0.0% 1.00x
ArrayAppendSequence 1062 1061 -0.1% 1.00x(?)
ArrayAppendArrayOfInt 599 599 +0.0% 1.00x
ArrayOfPOD 182 182 +0.0% 1.00x
ObserverForwarderStruct 899 895 -0.4% 1.00x(?)
ObjectiveCBridgeStubNSDataAppend 2398 2395 -0.1% 1.00x(?)
BitCount 1 1 +0.0% 1.00x
AngryPhonebook 2817 2815 -0.1% 1.00x(?)
SevenBoom 1355 1354 -0.1% 1.00x(?)
StringWalk 5879 5896 +0.3% 1.00x(?)
ArrayValueProp 6 6 +0.0% 1.00x
GlobalClass 0 0 +0.0% 1.00x
Memset 235 235 +0.0% 1.00x
ArrayValueProp4 6 6 +0.0% 1.00x
ArrayValueProp2 6 6 +0.0% 1.00x
ArrayValueProp3 6 6 +0.0% 1.00x
ObserverPartiallyAppliedMethod 3338 3345 +0.2% 1.00x(?)
DictionaryBridge 3780 3834 +1.4% 0.99x(?)
ObjectiveCBridgeFromNSArrayAnyObjectForced 6082 6171 +1.5% 0.99x(?)
RangeAssignment 281 284 +1.1% 0.99x(?)
ArrayAppendLazyMap 842 852 +1.2% 0.99x(?)
ObjectAllocation 152 153 +0.7% 0.99x(?)
ArrayLiteral 1173 1181 +0.7% 0.99x(?)
StrComplexWalk 2886 2906 +0.7% 0.99x(?)
DictionaryOfObjects 2286 2312 +1.1% 0.99x(?)
Phonebook 7513 7613 +1.3% 0.99x
NSStringConversion 799 811 +1.5% 0.99x(?)
ObjectiveCBridgeStubFromArrayOfNSString 58803 59222 +0.7% 0.99x(?)
StringInterpolation 10778 10993 +2.0% 0.98x(?)
Join 464 472 +1.7% 0.98x
IterateData 2546 2597 +2.0% 0.98x
ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced 135467 138904 +2.5% 0.98x(?)
Dictionary2OfObjects 3378 3439 +1.8% 0.98x(?)
ObjectiveCBridgeFromNSDictionaryAnyObjectToString 209584 216079 +3.1% 0.97x(?)
ObjectiveCBridgeFromNSSetAnyObject 90521 93338 +3.1% 0.97x(?)
ObjectiveCBridgeFromNSSetAnyObjectToStringForced 106562 109768 +3.0% 0.97x(?)
146 3040151 3142544 +3.4% 0.97x
ObjectiveCBridgeFromNSDictionaryAnyObject 194886 203999 +4.7% 0.96x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToString 118010 122316 +3.6% 0.96x(?)
Dictionary3OfObjects 857 891 +4.0% 0.96x
Hanoi 3344 3472 +3.8% 0.96x
ObjectiveCBridgeFromNSArrayAnyObjectToStringForced 90346 94366 +4.5% 0.96x(?)
Dictionary3 511 536 +4.9% 0.95x(?)
ObjectiveCBridgeFromNSSetAnyObjectToString 141379 148838 +5.3% 0.95x(?)
**Unoptimized (Onone)**

Regression (12)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ObjectiveCBridgeToNSDictionary 16248 71100 +337.6% 0.23x
ObjectiveCBridgeToNSSet 15871 43706 +175.4% 0.36x
DictionaryRemove 17377 22842 +31.4% 0.76x
DictionaryRemoveOfObjects 46853 57040 +21.7% 0.82x
ObjectiveCBridgeFromNSDictionaryAnyObjectForced 7754 9094 +17.3% 0.85x
ProtocolDispatch 5605 6488 +15.8% 0.86x
ObjectiveCBridgeFromNSSetAnyObjectForced 7478 8607 +15.1% 0.87x
StringHasSuffix 1576 1746 +10.8% 0.90x
StringHasPrefix 1561 1672 +7.1% 0.93x
OpenClose 425 452 +6.3% 0.94x
ObjectiveCBridgeFromNSSetAnyObjectToString 155535 165862 +6.6% 0.94x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToStringForced 92206 97576 +5.8% 0.94x

Improvement (20)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
TypeFlood 210 198 -5.7% 1.06x(?)
SetIntersect_OfObjects 14090 13253 -5.9% 1.06x
Calculator 984 929 -5.6% 1.06x
SetIntersect 15199 14321 -5.8% 1.06x
Dictionary3OfObjects 2239 2085 -6.9% 1.07x
ObjectiveCBridgeStubFromNSDate 3993 3718 -6.9% 1.07x
DictionarySwapOfObjects 20841 19243 -7.7% 1.08x
RGBHistogramOfObjects 93478 86857 -7.1% 1.08x
SetIsSubsetOf 2449 2248 -8.2% 1.09x
Dictionary3 1607 1460 -9.2% 1.10x
Dictionary 2137 1937 -9.4% 1.10x
SetIsSubsetOf_OfObjects 2228 2032 -8.8% 1.10x
BitCount 108 96 -11.1% 1.12x
SetExclusiveOr 30625 26437 -13.7% 1.16x
Histogram 11731 9834 -16.2% 1.19x
RGBHistogram 44452 37212 -16.3% 1.19x
TwoSum 6577 5417 -17.6% 1.21x
SetUnion 18388 14883 -19.1% 1.24x
DictionarySwap 7510 5996 -20.2% 1.25x
NSDictionaryCastToSwift 8251 6223 -24.6% 1.33x

No Changes (115)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ArrayAppendGenericStructs 1348 1292 -4.2% 1.04x(?)
Dictionary2 4466 4302 -3.7% 1.04x
ObjectiveCBridgeFromNSSetAnyObjectToStringForced 125236 120376 -3.9% 1.04x(?)
AnyHashableWithAClass 80987 79004 -2.5% 1.03x
ObjectiveCBridgeToNSArray 30969 30064 -2.9% 1.03x(?)
DictionaryOfObjects 4890 4749 -2.9% 1.03x
ObjectiveCBridgeStubNSDataAppend 2835 2757 -2.8% 1.03x
ObjectiveCBridgeFromNSArrayAnyObjectForced 10606 10443 -1.5% 1.02x(?)
Prims 13597 13395 -1.5% 1.02x
ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced 142662 140430 -1.6% 1.02x(?)
ObjectiveCBridgeStubToArrayOfNSString 29930 29475 -1.5% 1.02x(?)
StrToInt 5910 5800 -1.9% 1.02x
ObjectiveCBridgeFromNSStringForced 3068 3052 -0.5% 1.01x
SortLettersInPlace 2569 2555 -0.5% 1.01x
PopFrontArray 24477 24343 -0.6% 1.01x(?)
StringInterpolation 15773 15622 -1.0% 1.01x(?)
ErrorHandling 3815 3772 -1.1% 1.01x(?)
ObjectAllocation 557 553 -0.7% 1.01x(?)
AngryPhonebook 2990 2974 -0.5% 1.01x(?)
ProtocolDispatch2 460 454 -1.3% 1.01x(?)
ObjectiveCBridgeStubURLAppendPathRef 235454 233760 -0.7% 1.01x(?)
ObjectiveCBridgeStubToNSDateRef 3331 3313 -0.5% 1.01x(?)
StringEqualPointerComparison 9654 9532 -1.3% 1.01x
CaptureProp 118962 118278 -0.6% 1.01x
PolymorphicCalls 1152 1137 -1.3% 1.01x
DictionaryLiteral 16550 16316 -1.4% 1.01x(?)
Hanoi 19678 19528 -0.8% 1.01x
Phonebook 63677 63009 -1.1% 1.01x(?)
StringHasPrefixUnicode 15529 15319 -1.4% 1.01x(?)
LinkedList 27866 27572 -1.1% 1.01x
NSStringConversion 3033 3006 -0.9% 1.01x(?)
ArraySubscript 5619 5639 +0.4% 1.00x(?)
MonteCarloPi 53595 53579 -0.0% 1.00x(?)
Integrate 368 368 +0.0% 1.00x
ClassArrayGetter 1265 1265 +0.0% 1.00x
Array2D 812819 814193 +0.2% 1.00x(?)
StringWithCString 153371 152635 -0.5% 1.00x
RangeAssignment 13246 13280 +0.3% 1.00x(?)
ByteSwap 9 9 +0.0% 1.00x
SuperChars 263865 262860 -0.4% 1.00x(?)
ArrayAppendLazyMap 244769 244685 -0.0% 1.00x(?)
XorLoop 19999 20010 +0.1% 1.00x(?)
ObserverClosure 6945 6946 +0.0% 1.00x(?)
ObjectiveCBridgeStubToNSString 1334 1334 +0.0% 1.00x
ArrayAppendStrings 11849 11834 -0.1% 1.00x(?)
HashTest 5244 5263 +0.4% 1.00x(?)
StrComplexWalk 8064 8075 +0.1% 1.00x(?)
Join 1460 1457 -0.2% 1.00x(?)
ArrayOfRef 9133 9148 +0.2% 1.00x(?)
ObserverUnappliedMethod 8693 8690 -0.0% 1.00x(?)
ObjectiveCBridgeStubDateMutation 517 517 +0.0% 1.00x
PopFrontArrayGeneric 9705 9714 +0.1% 1.00x(?)
PopFrontUnsafePointer 242508 242703 +0.1% 1.00x(?)
ObjectiveCBridgeStubToNSStringRef 155 155 +0.0% 1.00x
ArrayAppendOptionals 1297 1291 -0.5% 1.00x(?)
UTF8Decode 43540 43638 +0.2% 1.00x
ObjectiveCBridgeStubURLAppendPath 238749 238139 -0.3% 1.00x(?)
SortStringsUnicode 9224 9229 +0.1% 1.00x(?)
ObjectiveCBridgeStubDataAppend 3318 3326 +0.2% 1.00x(?)
ObjectiveCBridgeStubNSDateRefAccess 1232 1228 -0.3% 1.00x(?)
ArrayInClass 3958 3957 -0.0% 1.00x(?)
ArrayOfGenericRef 10058 10035 -0.2% 1.00x(?)
ObjectiveCBridgeFromNSString 5104 5095 -0.2% 1.00x(?)
Sim2DArray 14780 14783 +0.0% 1.00x(?)
SetExclusiveOr_OfObjects 46941 46776 -0.3% 1.00x
ArrayAppendRepeatCol 212900 212224 -0.3% 1.00x(?)
MonteCarloE 108890 108623 -0.2% 1.00x(?)
RC4 9402 9395 -0.1% 1.00x(?)
Walsh 13318 13322 +0.0% 1.00x(?)
ArrayAppend 3552 3554 +0.1% 1.00x(?)
MapReduce 45039 45019 -0.0% 1.00x(?)
ArrayAppendArrayOfInt 641 641 +0.0% 1.00x
ArrayOfPOD 2515 2513 -0.1% 1.00x(?)
Chars 5023 5042 +0.4% 1.00x
ObserverForwarderStruct 5207 5213 +0.1% 1.00x(?)
ArrayLiteral 1252 1248 -0.3% 1.00x(?)
ArrayValueProp3 3072 3070 -0.1% 1.00x(?)
ArrayValueProp4 3020 3023 +0.1% 1.00x(?)
ArrayValueProp 2635 2636 +0.0% 1.00x(?)
GlobalClass 0 0 +0.0% 1.00x
Memset 20953 20959 +0.0% 1.00x(?)
Dictionary2OfObjects 6325 6306 -0.3% 1.00x(?)
ArrayAppendReserved 3298 3303 +0.1% 1.00x(?)
ArrayValueProp2 3146 3152 +0.2% 1.00x(?)
SevenBoom 1513 1513 +0.0% 1.00x
ObserverPartiallyAppliedMethod 8336 8316 -0.2% 1.00x(?)
ObjectiveCBridgeToNSString 1100 1110 +0.9% 0.99x
StackPromo 128293 129589 +1.0% 0.99x(?)
RecursiveOwnedParameter 10884 10960 +0.7% 0.99x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToString 121020 122658 +1.4% 0.99x(?)
SortStrings 2740 2767 +1.0% 0.99x(?)
ObjectiveCBridgeStubFromNSDateRef 4019 4076 +1.4% 0.99x
ObjectiveCBridgeStubFromNSString 798 803 +0.6% 0.99x(?)
StringHasSuffixUnicode 64506 65023 +0.8% 0.99x
NSError 674 683 +1.3% 0.99x(?)
IterateData 10572 10629 +0.5% 0.99x
ObjectiveCBridgeStubDateAccess 1090 1097 +0.6% 0.99x(?)
SetUnion_OfObjects 34390 34806 +1.2% 0.99x
ObjectiveCBridgeFromNSDictionaryAnyObjectToString 220662 225355 +2.1% 0.98x(?)
ObjectiveCBridgeStubToNSDate 13992 14242 +1.8% 0.98x(?)
StaticArray 34887 35425 +1.5% 0.98x(?)
StringBuilder 2700 2748 +1.8% 0.98x(?)
ArrayAppendSequence 105810 108085 +2.1% 0.98x
146 5998987 6135620 +2.3% 0.98x
DeadArray 119178 121204 +1.7% 0.98x(?)
ObjectiveCBridgeFromNSArrayAnyObject 79157 81404 +2.8% 0.97x(?)
StringWalk 22082 22820 +3.3% 0.97x
ObjectiveCBridgeStubNSDateMutationRef 13827 14247 +3.0% 0.97x(?)
ObjectiveCBridgeFromNSDictionaryAnyObject 200337 208785 +4.2% 0.96x
DictionaryBridge 3908 4065 +4.0% 0.96x
ObjectiveCBridgeFromNSSetAnyObject 94545 98619 +4.3% 0.96x(?)
ObjectiveCBridgeStubFromArrayOfNSString 59303 61857 +4.3% 0.96x(?)
ObjectiveCBridgeStubFromNSStringRef 164 173 +5.5% 0.95x
ArrayOfGenericPOD 3520 3702 +5.2% 0.95x
NopDeinit 58098 61126 +5.2% 0.95x
**Hardware Overview** Model Name: Mac mini Model Identifier: Macmini7,1 Processor Name: Intel Core i5 Processor Speed: 2.8 GHz Number of Processors: 1 Total Number of Cores: 2 L2 Cache (per Core): 256 KB L3 Cache: 3 MB Memory: 16 GB

@swift-ci
Copy link
Contributor

swift-ci commented Nov 4, 2016

Build comment file:

Optimized (O)

Regression (5)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ObjectiveCBridgeToNSDictionary 15307 59296 +287.4% 0.26x
ObjectiveCBridgeToNSSet 14918 37842 +153.7% 0.39x
ObjectiveCBridgeFromNSSetAnyObjectForced 4300 5379 +25.1% 0.80x
ObjectiveCBridgeFromNSDictionaryAnyObjectForced 4969 6121 +23.2% 0.81x
ObserverForwarderStruct 843 928 +10.1% 0.91x(?)

Improvement (24)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
AnyHashableWithAClass 62814 59352 -5.5% 1.06x
OpenClose 56 53 -5.4% 1.06x(?)
StrToInt 5175 4898 -5.3% 1.06x
SetUnion_OfObjects 6270 5932 -5.4% 1.06x
SetExclusiveOr_OfObjects 7507 7029 -6.4% 1.07x(?)
DictionarySwapOfObjects 6368 5918 -7.1% 1.08x
ObjectiveCBridgeFromNSDictionaryAnyObject 183663 169182 -7.9% 1.09x(?)
MapReduce 352 323 -8.2% 1.09x
StringHasPrefix 690 603 -12.6% 1.14x
PopFrontArray 1186 1029 -13.2% 1.15x(?)
ProtocolDispatch2 176 149 -15.3% 1.18x
TwoSum 1494 1261 -15.6% 1.18x
CaptureProp 4602 3855 -16.2% 1.19x
RGBHistogram 2670 2151 -19.4% 1.24x
NSDictionaryCastToSwift 6552 4687 -28.5% 1.40x
SetUnion 2822 1999 -29.2% 1.41x
DictionarySwap 596 401 -32.7% 1.49x
SetIntersect_OfObjects 2141 1370 -36.0% 1.56x
SetIsSubsetOf_OfObjects 494 286 -42.1% 1.73x
DictionaryRemove 4345 2170 -50.1% 2.00x
SetIsSubsetOf 480 229 -52.3% 2.10x
DictionaryLiteral 2597 1197 -53.9% 2.17x
Histogram 619 269 -56.5% 2.30x
SetIntersect 1023 334 -67.3% 3.06x

No Changes (118)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ObjectiveCBridgeFromNSString 1741 1665 -4.4% 1.05x(?)
ObjectiveCBridgeFromNSSetAnyObjectToStringForced 99724 94931 -4.8% 1.05x(?)
ObjectiveCBridgeFromNSDictionaryAnyObjectToString 199283 191065 -4.1% 1.04x(?)
ObjectiveCBridgeFromNSSetAnyObject 84906 81680 -3.8% 1.04x(?)
ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced 127986 122578 -4.2% 1.04x(?)
NopDeinit 35859 34553 -3.6% 1.04x
SortStrings 1733 1687 -2.6% 1.03x
ObjectiveCBridgeStubURLAppendPathRef 222758 215698 -3.2% 1.03x(?)
Calculator 34 33 -2.9% 1.03x
ObjectiveCBridgeStubURLAppendPath 223235 216213 -3.1% 1.03x(?)
SortStringsUnicode 7864 7631 -3.0% 1.03x
ObjectiveCBridgeStubFromNSDate 3435 3335 -2.9% 1.03x
DictionaryBridge 3612 3534 -2.2% 1.02x(?)
ObjectiveCBridgeStubToNSDate 12901 12594 -2.4% 1.02x(?)
Dictionary2 1944 1906 -1.9% 1.02x
Dictionary 699 684 -2.1% 1.02x
ArrayInClass 60 59 -1.7% 1.02x(?)
RGBHistogramOfObjects 20756 20390 -1.8% 1.02x(?)
DeadArray 175 172 -1.7% 1.02x
StackPromo 20408 20274 -0.7% 1.01x(?)
Prims 695 687 -1.1% 1.01x(?)
SuperChars 200267 199136 -0.6% 1.01x(?)
Walsh 294 292 -0.7% 1.01x
ObserverUnappliedMethod 2230 2217 -0.6% 1.01x(?)
ObjectiveCBridgeStubToNSDateRef 3108 3063 -1.4% 1.01x(?)
PopFrontUnsafePointer 8659 8612 -0.5% 1.01x(?)
StringEqualPointerComparison 6943 6889 -0.8% 1.01x
DictionaryRemoveOfObjects 18620 18483 -0.7% 1.01x(?)
ObjectiveCBridgeStubToArrayOfNSString 28186 27853 -1.2% 1.01x(?)
ObjectiveCBridgeFromNSArrayAnyObject 71493 71007 -0.7% 1.01x(?)
MonteCarloE 9902 9835 -0.7% 1.01x(?)
HashTest 1652 1639 -0.8% 1.01x(?)
Chars 594 589 -0.8% 1.01x
ObjectiveCBridgeFromNSArrayAnyObjectToStringForced 85967 85202 -0.9% 1.01x(?)
ObjectiveCBridgeStubFromArrayOfNSString 55579 54943 -1.1% 1.01x(?)
ObjectiveCBridgeStubNSDateMutationRef 11367 11218 -1.3% 1.01x(?)
ObjectiveCBridgeToNSString 1011 1011 +0.0% 1.00x
MonteCarloPi 42469 42465 -0.0% 1.00x(?)
RecursiveOwnedParameter 1824 1828 +0.2% 1.00x
ObjectiveCBridgeStubToNSString 1209 1210 +0.1% 1.00x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToString 110654 110976 +0.3% 1.00x(?)
ClassArrayGetter 12 12 +0.0% 1.00x
Array2D 1941 1938 -0.1% 1.00x(?)
ObjectiveCBridgeStubFromNSDateRef 3500 3494 -0.2% 1.00x(?)
ObjectiveCBridgeFromNSStringForced 2520 2527 +0.3% 1.00x(?)
SortLettersInPlace 919 918 -0.1% 1.00x(?)
ByteSwap 0 0 +0.0% 1.00x
ArrayAppendGenericStructs 1142 1142 +0.0% 1.00x
ArrayAppendLazyMap 799 799 +0.0% 1.00x
XorLoop 358 359 +0.3% 1.00x(?)
ArrayAppendReserved 506 506 +0.0% 1.00x
ObserverClosure 1838 1843 +0.3% 1.00x(?)
ArrayAppendStrings 11372 11367 -0.0% 1.00x(?)
Join 436 438 +0.5% 1.00x(?)
ProtocolDispatch 2868 2868 +0.0% 1.00x
TypeFlood 0 0 +0.0% 1.00x
AngryPhonebook 2653 2663 +0.4% 1.00x(?)
ErrorHandling 2758 2756 -0.1% 1.00x(?)
ObjectiveCBridgeStubDateMutation 258 258 +0.0% 1.00x
ObjectiveCBridgeToNSArray 28870 28921 +0.2% 1.00x(?)
NSError 306 307 +0.3% 1.00x(?)
DictionaryOfObjects 2155 2152 -0.1% 1.00x(?)
PolymorphicCalls 20 20 +0.0% 1.00x
RC4 156 156 +0.0% 1.00x
ObjectiveCBridgeStubToNSStringRef 109 109 +0.0% 1.00x
ArrayAppendOptionals 1141 1143 +0.2% 1.00x(?)
IterateData 2402 2396 -0.2% 1.00x
ArrayOfGenericPOD 207 207 +0.0% 1.00x
UTF8Decode 272 272 +0.0% 1.00x
ObjectiveCBridgeStubNSDateRefAccess 291 291 +0.0% 1.00x
StringBuilder 1238 1241 +0.2% 1.00x(?)
StringHasSuffix 755 757 +0.3% 1.00x
ObjectiveCBridgeStubDateAccess 172 172 +0.0% 1.00x
Sim2DArray 261 261 +0.0% 1.00x
ArrayAppendRepeatCol 607 607 +0.0% 1.00x
StringHasSuffixUnicode 59550 59584 +0.1% 1.00x(?)
ArrayAppend 732 730 -0.3% 1.00x(?)
LinkedList 6862 6867 +0.1% 1.00x(?)
ArrayAppendSequence 1002 1001 -0.1% 1.00x(?)
ArrayAppendArrayOfInt 565 565 +0.0% 1.00x
ArrayOfPOD 171 171 +0.0% 1.00x
BitCount 1 1 +0.0% 1.00x
ArrayLiteral 1105 1108 +0.3% 1.00x(?)
ArrayValueProp3 5 5 +0.0% 1.00x
StringWalk 5566 5564 -0.0% 1.00x(?)
ArrayValueProp 5 5 +0.0% 1.00x
GlobalClass 0 0 +0.0% 1.00x
Memset 222 222 +0.0% 1.00x
ArrayValueProp4 5 5 +0.0% 1.00x
ArrayValueProp2 5 5 +0.0% 1.00x
SevenBoom 1276 1278 +0.2% 1.00x(?)
ObserverPartiallyAppliedMethod 3181 3175 -0.2% 1.00x(?)
StringWithCString 146218 146965 +0.5% 0.99x(?)
ObjectiveCBridgeFromNSArrayAnyObjectForced 5875 5908 +0.6% 0.99x(?)
Dictionary3OfObjects 809 821 +1.5% 0.99x(?)
StringInterpolation 10069 10209 +1.4% 0.99x(?)
Integrate 225 227 +0.9% 0.99x(?)
ObjectAllocation 144 145 +0.7% 0.99x(?)
Dictionary3 482 487 +1.0% 0.99x
StrComplexWalk 2727 2745 +0.7% 0.99x(?)
ArrayOfRef 3320 3356 +1.1% 0.99x(?)
ObjectiveCBridgeFromNSSetAnyObjectToString 133513 134579 +0.8% 0.99x(?)
ArrayOfGenericRef 3388 3418 +0.9% 0.99x(?)
Phonebook 7083 7125 +0.6% 0.99x
StringHasPrefixUnicode 12932 13119 +1.4% 0.99x(?)
ObjectiveCBridgeStubNSDataAppend 2262 2290 +1.2% 0.99x(?)
RangeAssignment 266 272 +2.3% 0.98x(?)
PopFrontArrayGeneric 1028 1051 +2.2% 0.98x(?)
ObjectiveCBridgeStubDataAppend 2774 2825 +1.8% 0.98x(?)
SetExclusiveOr 2475 2519 +1.8% 0.98x(?)
NSStringConversion 754 770 +2.1% 0.98x
146 2835701 2885663 +1.8% 0.98x
Dictionary2OfObjects 3198 3248 +1.6% 0.98x(?)
ObjectiveCBridgeStubFromNSString 720 742 +3.1% 0.97x
StaticArray 2494 2580 +3.5% 0.97x(?)
Hanoi 3154 3246 +2.9% 0.97x(?)
ObjectiveCBridgeStubFromNSStringRef 123 128 +4.1% 0.96x
ArraySubscript 1359 1438 +5.8% 0.95x
**Unoptimized (Onone)**

Regression (5)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ObjectiveCBridgeToNSDictionary 15532 59882 +285.5% 0.26x
ObjectiveCBridgeToNSSet 15132 38277 +152.9% 0.40x
ObjectiveCBridgeFromNSDictionaryAnyObjectForced 7261 8506 +17.1% 0.85x
ObjectiveCBridgeFromNSSetAnyObjectForced 7027 8171 +16.3% 0.86x
StringWalk 21010 22534 +7.2% 0.93x

Improvement (26)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
StrComplexWalk 7623 7201 -5.5% 1.06x
BitCount 101 95 -5.9% 1.06x
Dictionary2OfObjects 5949 5602 -5.8% 1.06x
ObjectiveCBridgeFromNSDictionaryAnyObject 188296 175510 -6.8% 1.07x
DictionaryOfObjects 4628 4302 -7.0% 1.08x
ArrayOfPOD 2370 2195 -7.4% 1.08x
DictionarySwapOfObjects 19816 18127 -8.5% 1.09x
Dictionary2 4202 3824 -9.0% 1.10x(?)
RGBHistogramOfObjects 88320 79649 -9.8% 1.11x
Dictionary3OfObjects 2113 1890 -10.6% 1.12x
ObjectiveCBridgeStubDateMutation 488 430 -11.9% 1.13x
SetIsSubsetOf 2307 2012 -12.8% 1.15x
Dictionary 2015 1752 -13.1% 1.15x
Dictionary3 1514 1307 -13.7% 1.16x
SetIntersect 14330 12322 -14.0% 1.16x
SetExclusiveOr_OfObjects 44349 37832 -14.7% 1.17x
SetIsSubsetOf_OfObjects 2102 1795 -14.6% 1.17x
SetIntersect_OfObjects 13258 11211 -15.4% 1.18x
Histogram 11044 9276 -16.0% 1.19x
SetUnion_OfObjects 32445 26488 -18.4% 1.22x
RGBHistogram 41977 34088 -18.8% 1.23x
DictionarySwap 7099 5705 -19.6% 1.24x
SetExclusiveOr 28837 22274 -22.8% 1.29x
TwoSum 6229 4697 -24.6% 1.33x
NSDictionaryCastToSwift 7768 5799 -25.4% 1.34x
SetUnion 17299 11380 -34.2% 1.52x

No Changes (116)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
DictionaryLiteral 15576 14823 -4.8% 1.05x
ObjectiveCBridgeFromNSSetAnyObjectToStringForced 111069 105444 -5.1% 1.05x(?)
ObjectiveCBridgeFromNSDictionaryAnyObjectToString 208764 201588 -3.4% 1.04x(?)
ObjectiveCBridgeFromNSSetAnyObject 90201 86943 -3.6% 1.04x(?)
ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced 133694 128262 -4.1% 1.04x(?)
StackPromo 122844 119601 -2.6% 1.03x(?)
ArrayOfGenericPOD 3320 3237 -2.5% 1.03x
Prims 12839 12525 -2.5% 1.03x
ProtocolDispatch 5303 5163 -2.6% 1.03x
ObjectiveCBridgeFromNSSetAnyObjectToString 151224 146593 -3.1% 1.03x(?)
DictionaryRemove 16380 15944 -2.7% 1.03x
AnyHashableWithAClass 76448 74647 -2.4% 1.02x
PolymorphicCalls 1085 1065 -1.8% 1.02x(?)
ArrayAppendSequence 99720 97475 -2.2% 1.02x
ObjectiveCBridgeStubFromNSDate 3759 3671 -2.3% 1.02x
ObjectiveCBridgeFromNSArrayAnyObjectForced 9740 9686 -0.6% 1.01x(?)
ObjectiveCBridgeStubToNSDate 13345 13212 -1.0% 1.01x(?)
StringInterpolation 14896 14707 -1.3% 1.01x(?)
Join 1391 1379 -0.9% 1.01x(?)
ObjectiveCBridgeStubFromNSStringRef 155 153 -1.3% 1.01x(?)
ObjectAllocation 530 527 -0.6% 1.01x(?)
AngryPhonebook 2818 2802 -0.6% 1.01x(?)
ProtocolDispatch2 434 430 -0.9% 1.01x
CaptureProp 112002 111092 -0.8% 1.01x
DictionaryRemoveOfObjects 44195 43904 -0.7% 1.01x
ArrayAppendRepeatCol 200889 198826 -1.0% 1.01x
LinkedList 26276 25990 -1.1% 1.01x(?)
NSStringConversion 2861 2841 -0.7% 1.01x(?)
146 5677511 5612658 -1.1% 1.01x
DeadArray 113857 113164 -0.6% 1.01x(?)
ObjectiveCBridgeStubNSDataAppend 2676 2639 -1.4% 1.01x(?)
ObjectiveCBridgeStubFromArrayOfNSString 55808 55525 -0.5% 1.01x(?)
ArraySubscript 5289 5310 +0.4% 1.00x(?)
ObjectiveCBridgeToNSString 1041 1041 +0.0% 1.00x
MonteCarloPi 50597 50680 +0.2% 1.00x
PopFrontArray 23125 23075 -0.2% 1.00x(?)
RecursiveOwnedParameter 10282 10268 -0.1% 1.00x(?)
ObjectiveCBridgeStubToNSString 1259 1261 +0.2% 1.00x(?)
ClassArrayGetter 1194 1194 +0.0% 1.00x
Array2D 766665 767220 +0.1% 1.00x(?)
StringWithCString 144769 144278 -0.3% 1.00x
ObjectiveCBridgeFromNSStringForced 2893 2901 +0.3% 1.00x
SortLettersInPlace 2415 2410 -0.2% 1.00x(?)
ObjectiveCBridgeFromNSString 4821 4818 -0.1% 1.00x(?)
RangeAssignment 12484 12512 +0.2% 1.00x(?)
ByteSwap 9 9 +0.0% 1.00x
ArrayAppendGenericStructs 1185 1186 +0.1% 1.00x(?)
SuperChars 221688 220613 -0.5% 1.00x(?)
ArrayAppendLazyMap 230694 231390 +0.3% 1.00x
XorLoop 18865 18866 +0.0% 1.00x(?)
ObserverClosure 6565 6569 +0.1% 1.00x(?)
Integrate 347 347 +0.0% 1.00x
ArrayAppendStrings 11101 11106 +0.1% 1.00x(?)
StaticArray 33358 33380 +0.1% 1.00x(?)
HashTest 4942 4966 +0.5% 1.00x(?)
StringHasPrefix 1472 1465 -0.5% 1.00x
ArrayOfRef 8633 8613 -0.2% 1.00x(?)
ObserverUnappliedMethod 8207 8219 +0.1% 1.00x(?)
ObjectiveCBridgeStubURLAppendPathRef 225323 224787 -0.2% 1.00x(?)
ArrayAppendOptionals 1186 1184 -0.2% 1.00x(?)
ObjectiveCBridgeToNSArray 28856 28956 +0.3% 1.00x(?)
PopFrontUnsafePointer 228946 228837 -0.1% 1.00x(?)
StringEqualPointerComparison 9105 9087 -0.2% 1.00x
ObjectiveCBridgeStubToNSStringRef 147 147 +0.0% 1.00x
MapReduce 42502 42568 +0.2% 1.00x
Hanoi 18514 18600 +0.5% 1.00x(?)
ObjectiveCBridgeStubURLAppendPath 223920 223314 -0.3% 1.00x(?)
NopDeinit 54801 54824 +0.0% 1.00x(?)
ObjectiveCBridgeStubToArrayOfNSString 28261 28159 -0.4% 1.00x(?)
ObjectiveCBridgeFromNSArrayAnyObject 74787 74587 -0.3% 1.00x(?)
GlobalClass 0 0 +0.0% 1.00x
ObjectiveCBridgeStubNSDateRefAccess 1163 1159 -0.3% 1.00x
StrToInt 5573 5596 +0.4% 1.00x(?)
ArrayInClass 3736 3734 -0.1% 1.00x(?)
ArrayOfGenericRef 9476 9488 +0.1% 1.00x(?)
Phonebook 59737 60001 +0.4% 1.00x(?)
Sim2DArray 13937 13955 +0.1% 1.00x(?)
MonteCarloE 102661 102505 -0.1% 1.00x
StringHasSuffixUnicode 61016 61315 +0.5% 1.00x
Walsh 12572 12597 +0.2% 1.00x(?)
ArrayAppend 3351 3351 +0.0% 1.00x
ArrayAppendArrayOfInt 603 604 +0.2% 1.00x(?)
Chars 4730 4716 -0.3% 1.00x
ObserverForwarderStruct 4907 4908 +0.0% 1.00x(?)
ArrayLiteral 1179 1180 +0.1% 1.00x(?)
SevenBoom 1424 1429 +0.3% 1.00x(?)
ArrayValueProp4 2835 2838 +0.1% 1.00x(?)
ArrayValueProp 2487 2486 -0.0% 1.00x(?)
ObjectiveCBridgeStubNSDateMutationRef 13290 13354 +0.5% 1.00x(?)
RC4 8873 8856 -0.2% 1.00x
Memset 19778 19780 +0.0% 1.00x(?)
ArrayAppendReserved 3114 3116 +0.1% 1.00x
ArrayValueProp2 2967 2971 +0.1% 1.00x
ArrayValueProp3 2898 2897 -0.0% 1.00x(?)
ObserverPartiallyAppliedMethod 7867 7868 +0.0% 1.00x(?)
SortStrings 2584 2599 +0.6% 0.99x(?)
ErrorHandling 3562 3616 +1.5% 0.99x(?)
PopFrontArrayGeneric 9090 9184 +1.0% 0.99x
IterateData 9964 10031 +0.7% 0.99x
SortStringsUnicode 8694 8750 +0.6% 0.99x(?)
ObjectiveCBridgeStubDataAppend 3130 3177 +1.5% 0.99x(?)
StringHasSuffix 1486 1499 +0.9% 0.99x
StringBuilder 2555 2583 +1.1% 0.99x(?)
DictionaryBridge 3658 3745 +2.4% 0.98x(?)
ObjectiveCBridgeStubFromNSString 754 773 +2.5% 0.98x
NSError 639 650 +1.7% 0.98x(?)
ObjectiveCBridgeStubToNSDateRef 3130 3199 +2.2% 0.98x(?)
Calculator 928 948 +2.2% 0.98x
UTF8Decode 41060 41688 +1.5% 0.98x(?)
StringHasPrefixUnicode 14649 14940 +2.0% 0.98x
ObjectiveCBridgeStubDateAccess 1029 1062 +3.2% 0.97x
ObjectiveCBridgeStubFromNSDateRef 3795 3937 +3.7% 0.96x
OpenClose 397 415 +4.5% 0.96x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToString 112189 117499 +4.7% 0.95x(?)
TypeFlood 187 197 +5.3% 0.95x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToStringForced 88507 92934 +5.0% 0.95x(?)
**Hardware Overview** Model Name: Mac mini Model Identifier: Macmini7,1 Processor Name: Intel Core i7 Processor Speed: 3 GHz Number of Processors: 1 Total Number of Cores: 2 L2 Cache (per Core): 256 KB L3 Cache: 4 MB Memory: 16 GB

@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

@swift-ci Please smoke test

@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

Heck yeah, those are some perf numbers I can get behind! 😎

@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

Oh god all tests passed I'm scared what do I do can I just push that big green button is this real oh god oh god oh god 😱

@Gankra Gankra merged commit c565c7c into swiftlang:master Nov 4, 2016
@Gankra
Copy link
Contributor Author

Gankra commented Nov 4, 2016

@bob-wilson here's my perf analysis:

The two biggest regressions are the result of removing the bridging cache that Dictionaries implicitly had. This means that (in the worst case):

for _ in 0..<100 {
  myDict as NSDictionary
}

creates 100 independent _SwiftDeferredNSDictionary with independent "bridged buffer" caches, where previously it would just return the same one over and over. If this is considered problematic, we can potentially add a weak pointer caching a _SwiftDeferredNSDictionary to _RawNativeDictionaryStorage (or maybe only _HashableTypedNativeDictionaryStorage).

I haven't dug into the other regressions, but it's worth noting that this PR changed the representation of a lazy bridged dictionary (_VariantDictionaryStorage.cocoa) to be a class, where previously it was a struct to allow lazy var to be used. Reverting this might be the right solution; I didn't obsess over this since eager bridging may just delete all that code.

@dabrahams
Copy link
Contributor

Congratulations @gankro and @austinzheng !

@bob-wilson
Copy link
Contributor

@gankro Since you and Dave already discussed the performance tradeoff and concluded that this is the right thing to do, I'm not going to second guess that. If you don't end up deleting the code with eager bridging, can you come back and take another look at the performance later?

@dabrahams
Copy link
Contributor

@gankro @bob-wilson Actually I am unclear on why this should cause any regressions at all, so maybe we should discuss that.

@Gankra
Copy link
Contributor Author

Gankra commented Nov 10, 2016

This should cause a regression (at least in synthetic benchmarks) because:

  • It eliminates the repeated-bridging cache (possibly only a problem for micro benchmarks that bridge in a loop?). We can in principle add this back, at the cost of storing a weak or strong pointer (depending on how eagerly you want to free that cached allocation) in every _RawNative${Self}Storage.
  • It requires a _SwiftDeferredNSDictionary to be eagerly allocated to wrap the the two _Native${Self}Buffers. We can in principle eliminate this by making that hypothetical pointer into a strong pointer, and having the NSDictionary implementation branch on whether K/V is verbatim bridgeable for every operation.

The former is potentially desirable, the latter is probably a huge waste.

This is an unavoidable consequence of making Dictionary into a single-allocation data structure. A lot of optimizations were built around there being two allocations. In effect, we've taken the cost of allocating an extra class from every dictionary, and pushed it into every bridge. I consider that an acceptable trade-off.

@Gankra
Copy link
Contributor Author

Gankra commented Nov 10, 2016

Mental reworking: we can move the verbatim bridgeable check to Storage construction time, and just fork _HashableTypedNative${Self}Storage into two types. The one that exists now, and one that has the slot for a strong pointer to the bridged buffer. This means Dictionary<Int, Int> would store a potentially unused pointer, while Dictionary<MyClass, MyClass> wouldn't. Much better.

@Gankra
Copy link
Contributor Author

Gankra commented Nov 10, 2016

Followup from private conversation:

@dabrahams we definitely need/want to add a new Storage class so that every method doesn't have to be guarded by "am I verbatim bridgeable", unless I'm missing something.

Also I'm remembering now that we dicussed this design like a month ago; I believe we concluded that storing a strong pointer in the storage is unacceptable, because that is an easy source of memory leaks. However whatever we return to ObjC must store a strong pointer. Note that the solution implemented by this PR is the solution used by Array; see _SwiftDeferredNSArray (which I modelled this solution after).

@dabrahams
Copy link
Contributor

on Thu Nov 10 2016, Alexis Beingessner <notifications-AT-i.8713187.xyz> wrote:

Followup from private conversation:

@dabrahams we definitely need/want to add a new Storage class so that
every method doesn't have to be guarded by "am I verbatim bridgeable",
unless I'm missing something.

That check gets compiled down to nothing any place where the static type
of the element is visible, so that cost is dramatically less than you
might assume.

Also I'm remembering now that we dicussed this design like a month
ago; I believe we concluded that storing a strong pointer in the
storage is unacceptable, because that is an easy source of memory
leaks. However whatever we return to ObjC must store a strong
pointer. Note that the solution implemented by this PR is the solution
used by Array; see _SwiftDeferredNSArray (which I modelled this
solution after).

Eh, I think I'll need an interactive refresher on that discussion.

-Dave

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.

8 participants