Skip to content

improve set's conditional downcast performance by over 2X #5264

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 1 commit into from
Oct 19, 2016

Conversation

shajrawi
Copy link

radar rdar://problem/27513079

9a2783f regressed the performance of some benchmarks by over 2X, I traced the problem back to set's conditional downcast implementation.

Using Collection.map -> [A1] to create the Set has a high overhead (see new_run.trace instruments output attached to radar), pre-creation of a Set with a known capacity + iterating over source in a loop vastly improves performance (see fix_run.trace instruments output attached to radar)

@shajrawi
Copy link
Author

@dabrahams Can you please review?

@shajrawi
Copy link
Author

@swift-ci Please smoke test

@shajrawi
Copy link
Author

@swift-ci Please benchmark

@swift-ci
Copy link
Contributor

Build comment file:

Optimized (O)

Regression (0)

Improvement (3)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
135 3234941 3043614 -5.9% 1.06x
Calculator 33 31 -6.1% 1.06x
ObjectiveCBridgeFromNSSetAnyObject 271771 97248 -64.2% 2.79x

No Changes (133)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ObjectiveCBridgeStubToNSDate 15056 14580 -3.2% 1.03x(?)
ObjectiveCBridgeToNSDictionary 16981 16495 -2.9% 1.03x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToString 125009 122852 -1.7% 1.02x(?)
ObjectiveCBridgeToNSSet 16188 15930 -1.6% 1.02x(?)
IterateData 2599 2544 -2.1% 1.02x
SetExclusiveOr_OfObjects 7955 7836 -1.5% 1.02x(?)
NSStringConversion 824 810 -1.7% 1.02x
SetUnion 3070 3020 -1.6% 1.02x(?)
Chars 638 625 -2.0% 1.02x
ObjectiveCBridgeFromNSDictionaryAnyObjectForced 5297 5250 -0.9% 1.01x(?)
Dictionary3OfObjects 911 906 -0.6% 1.01x(?)
StringInterpolation 11863 11753 -0.9% 1.01x(?)
ObjectiveCBridgeStubToNSString 1402 1394 -0.6% 1.01x(?)
ErrorHandling 3362 3341 -0.6% 1.01x(?)
Dictionary3 519 514 -1.0% 1.01x(?)
AngryPhonebook 3195 3171 -0.8% 1.01x(?)
SortStringsUnicode 8180 8063 -1.4% 1.01x
Dictionary 751 746 -0.7% 1.01x(?)
SetExclusiveOr 2692 2665 -1.0% 1.01x(?)
SetUnion_OfObjects 6645 6552 -1.4% 1.01x(?)
ObjectiveCBridgeStubNSDateMutationRef 13582 13465 -0.9% 1.01x(?)
DictionaryRemove 4686 4645 -0.9% 1.01x(?)
StringHasPrefixUnicode 14041 13921 -0.8% 1.01x
ObjectiveCBridgeFromNSArrayAnyObjectToStringForced 91345 90598 -0.8% 1.01x(?)
ObjectiveCBridgeStubFromArrayOfNSString 59132 58829 -0.5% 1.01x(?)
TwoSum 1709 1695 -0.8% 1.01x(?)
ArraySubscript 1455 1454 -0.1% 1.00x(?)
StackPromo 21673 21636 -0.2% 1.00x(?)
RecursiveOwnedParameter 1935 1933 -0.1% 1.00x(?)
Integrate 239 238 -0.4% 1.00x(?)
ClassArrayGetter 14 14 +0.0% 1.00x
Array2D 2033 2037 +0.2% 1.00x(?)
Histogram 656 656 +0.0% 1.00x
ObjectiveCBridgeStubFromNSDateRef 3733 3733 +0.0% 1.00x
MonteCarloPi 44980 44972 -0.0% 1.00x(?)
StringWithCString 150456 150179 -0.2% 1.00x(?)
ObjectiveCBridgeFromNSStringForced 2644 2655 +0.4% 1.00x(?)
SortLettersInPlace 1059 1056 -0.3% 1.00x(?)
DictionarySwap 627 627 +0.0% 1.00x
ArrayOfGenericPOD 220 220 +0.0% 1.00x
RangeAssignment 273 273 +0.0% 1.00x
StringHasPrefix 609 609 +0.0% 1.00x
ByteSwap 0 0 +0.0% 1.00x
XorLoop 381 381 +0.0% 1.00x
ObjectiveCBridgeStubFromNSStringRef 128 128 +0.0% 1.00x
ProtocolDispatch 3040 3040 +0.0% 1.00x
TypeFlood 0 0 +0.0% 1.00x
ArrayLiteral 1216 1216 +0.0% 1.00x
ProtocolDispatch2 158 158 +0.0% 1.00x
Walsh 320 320 +0.0% 1.00x
Dictionary2 2208 2212 +0.2% 1.00x(?)
SetIntersect_OfObjects 2285 2282 -0.1% 1.00x(?)
Join 506 508 +0.4% 1.00x(?)
ObjectiveCBridgeStubURLAppendPathRef 238323 237148 -0.5% 1.00x(?)
ObjectiveCBridgeStubDateMutation 273 273 +0.0% 1.00x
DictionaryOfObjects 2577 2576 -0.0% 1.00x(?)
PopFrontArrayGeneric 1119 1117 -0.2% 1.00x(?)
PopFrontUnsafePointer 9197 9186 -0.1% 1.00x(?)
StringEqualPointerComparison 7295 7297 +0.0% 1.00x(?)
CaptureProp 4112 4116 +0.1% 1.00x(?)
PolymorphicCalls 22 22 +0.0% 1.00x
ObjectiveCBridgeStubToNSStringRef 117 117 +0.0% 1.00x
MapReduce 341 341 +0.0% 1.00x
Hanoi 3185 3185 +0.0% 1.00x
DictionaryRemoveOfObjects 20519 20540 +0.1% 1.00x(?)
UTF8Decode 288 288 +0.0% 1.00x
ObjectiveCBridgeStubURLAppendPath 238310 238313 +0.0% 1.00x(?)
SetIsSubsetOf 508 508 +0.0% 1.00x
NopDeinit 36655 36659 +0.0% 1.00x(?)
ObjectiveCBridgeFromNSArrayAnyObject 76549 76397 -0.2% 1.00x(?)
SetIntersect 1088 1089 +0.1% 1.00x(?)
ObjectiveCBridgeStubDataAppend 3070 3059 -0.4% 1.00x(?)
ObjectiveCBridgeStubNSDateRefAccess 308 308 +0.0% 1.00x
ArrayInClass 62 62 +0.0% 1.00x
StringHasSuffix 711 710 -0.1% 1.00x(?)
Phonebook 7065 7095 +0.4% 1.00x(?)
ObjectiveCBridgeStubDateAccess 182 182 +0.0% 1.00x
Sim2DArray 277 277 +0.0% 1.00x
MonteCarloE 10514 10517 +0.0% 1.00x(?)
StringHasSuffixUnicode 63518 63669 +0.2% 1.00x(?)
HashTest 1945 1939 -0.3% 1.00x(?)
SetIsSubsetOf_OfObjects 524 524 +0.0% 1.00x
ArrayAppend 774 775 +0.1% 1.00x(?)
LinkedList 7208 7207 -0.0% 1.00x(?)
ObjectiveCBridgeFromNSSetAnyObjectToStringForced 114926 114482 -0.4% 1.00x(?)
RGBHistogramOfObjects 24138 24207 +0.3% 1.00x(?)
RGBHistogram 2858 2864 +0.2% 1.00x(?)
ObjectiveCBridgeFromNSSetAnyObjectForced 4517 4539 +0.5% 1.00x(?)
ArrayValueProp4 6 6 +0.0% 1.00x
ArrayOfPOD 182 182 +0.0% 1.00x
DeadArray 182 182 +0.0% 1.00x
ArrayValueProp2 6 6 +0.0% 1.00x
BitCount 1 1 +0.0% 1.00x
AnyHashableWithAClass 62171 62084 -0.1% 1.00x(?)
SevenBoom 1594 1592 -0.1% 1.00x(?)
StringWalk 5881 5883 +0.0% 1.00x(?)
ArrayValueProp 6 6 +0.0% 1.00x
ObjectiveCBridgeFromNSString 1812 1808 -0.2% 1.00x(?)
GlobalClass 0 0 +0.0% 1.00x
Memset 235 235 +0.0% 1.00x
Dictionary2OfObjects 3851 3854 +0.1% 1.00x(?)
ArrayAppendReserved 536 537 +0.2% 1.00x(?)
ArrayValueProp3 6 6 +0.0% 1.00x
DictionarySwapOfObjects 7184 7288 +1.4% 0.99x(?)
PopFrontArray 1104 1119 +1.4% 0.99x(?)
SortStrings 1758 1771 +0.7% 0.99x(?)
DictionaryBridge 4002 4040 +0.9% 0.99x(?)
ObjectiveCBridgeFromNSArrayAnyObjectForced 6229 6267 +0.6% 0.99x(?)
Prims 758 763 +0.7% 0.99x(?)
ObjectiveCBridgeFromNSDictionaryAnyObject 204276 206093 +0.9% 0.99x(?)
SuperChars 217988 219096 +0.5% 0.99x(?)
StrComplexWalk 3085 3125 +1.3% 0.99x(?)
NSError 370 374 +1.1% 0.99x(?)
ObjectiveCBridgeStubToNSDateRef 3244 3267 +0.7% 0.99x(?)
RC4 164 165 +0.6% 0.99x
DictionaryLiteral 3252 3275 +0.7% 0.99x(?)
ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced 141944 144012 +1.5% 0.99x(?)
NSDictionaryCastToSwift 7876 7939 +0.8% 0.99x(?)
ObjectiveCBridgeFromNSSetAnyObjectToString 150132 151350 +0.8% 0.99x(?)
StringBuilder 1407 1427 +1.4% 0.99x(?)
StrToInt 4995 5059 +1.3% 0.99x
ObjectiveCBridgeStubNSDataAppend 2467 2495 +1.1% 0.99x(?)
ObjectiveCBridgeToNSString 1195 1216 +1.8% 0.98x(?)
StaticArray 3090 3167 +2.5% 0.98x(?)
ObjectAllocation 177 180 +1.7% 0.98x(?)
ArrayOfRef 4236 4330 +2.2% 0.98x(?)
ObjectiveCBridgeStubToArrayOfNSString 33693 34396 +2.1% 0.98x(?)
ObjectiveCBridgeStubFromNSDate 3350 3408 +1.7% 0.98x
ObjectiveCBridgeFromNSDictionaryAnyObjectToString 212103 218839 +3.2% 0.97x(?)
ObjectiveCBridgeStubFromNSString 773 793 +2.6% 0.97x
ObjectiveCBridgeToNSArray 34554 35718 +3.4% 0.97x(?)
ArrayOfGenericRef 4315 4435 +2.8% 0.97x(?)
OpenClose 54 57 +5.6% 0.95x
**Unoptimized (Onone)**

Regression (1)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
MonteCarloE 113450 121653 +7.2% 0.93x

Improvement (1)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ObjectiveCBridgeFromNSSetAnyObject 283193 102870 -63.7% 2.75x

No Changes (134)

TEST OLD_MIN NEW_MIN DELTA (%) SPEEDUP
ObjectiveCBridgeStubNSDateMutationRef 16447 15817 -3.8% 1.04x(?)
135 5750016 5573504 -3.1% 1.03x
ObjectiveCBridgeToNSSet 17070 16514 -3.3% 1.03x(?)
StackPromo 141762 139105 -1.9% 1.02x(?)
ErrorHandling 4287 4191 -2.2% 1.02x(?)
IterateData 10780 10603 -1.6% 1.02x(?)
ObjectiveCBridgeStubURLAppendPath 242871 239060 -1.6% 1.02x(?)
SortStringsUnicode 9245 9052 -2.1% 1.02x
StrToInt 5280 5179 -1.9% 1.02x
StringHasSuffix 1644 1610 -2.1% 1.02x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToString 128822 127735 -0.8% 1.01x(?)
Prims 13769 13700 -0.5% 1.01x(?)
RangeAssignment 30747 30335 -1.3% 1.01x(?)
StringHasPrefix 1651 1642 -0.6% 1.01x
ObjectiveCBridgeStubURLAppendPathRef 245300 242043 -1.3% 1.01x(?)
PolymorphicCalls 1155 1147 -0.7% 1.01x(?)
Phonebook 72811 72355 -0.6% 1.01x(?)
ObjectiveCBridgeToNSDictionary 17325 17154 -1.0% 1.01x(?)
LinkedList 27889 27714 -0.6% 1.01x(?)
ObjectiveCBridgeFromNSSetAnyObjectToStringForced 129174 127416 -1.4% 1.01x(?)
ArrayLiteral 1314 1306 -0.6% 1.01x(?)
SetUnion 18514 18366 -0.8% 1.01x(?)
ObjectiveCBridgeFromNSArrayAnyObjectToStringForced 92898 92288 -0.7% 1.01x(?)
ArrayValueProp 2787 2769 -0.7% 1.01x(?)
ArraySubscript 5628 5618 -0.2% 1.00x(?)
DictionarySwapOfObjects 21747 21661 -0.4% 1.00x(?)
PopFrontArray 23958 24020 +0.3% 1.00x(?)
RecursiveOwnedParameter 10867 10889 +0.2% 1.00x(?)
Integrate 368 368 +0.0% 1.00x
ClassArrayGetter 1267 1270 +0.2% 1.00x(?)
Array2D 813019 812934 -0.0% 1.00x(?)
Histogram 11993 12029 +0.3% 1.00x(?)
DictionaryBridge 4172 4192 +0.5% 1.00x(?)
ObjectiveCBridgeFromNSDictionaryAnyObjectForced 7678 7646 -0.4% 1.00x(?)
ObjectiveCBridgeStubFromNSDateRef 4195 4182 -0.3% 1.00x(?)
StringWithCString 205253 204357 -0.4% 1.00x
ObjectiveCBridgeFromNSStringForced 3063 3055 -0.3% 1.00x(?)
DictionarySwap 7576 7547 -0.4% 1.00x
ByteSwap 9 9 +0.0% 1.00x
ObjectiveCBridgeStubToNSDate 15829 15857 +0.2% 1.00x(?)
XorLoop 23115 23150 +0.1% 1.00x
ObjectiveCBridgeStubToNSString 1503 1500 -0.2% 1.00x(?)
ProtocolDispatch 5777 5777 +0.0% 1.00x
ObjectAllocation 639 640 +0.2% 1.00x(?)
ProtocolDispatch2 449 449 +0.0% 1.00x
Walsh 13279 13264 -0.1% 1.00x(?)
Dictionary3 1637 1640 +0.2% 1.00x(?)
Dictionary2 4602 4586 -0.3% 1.00x(?)
Join 1505 1503 -0.1% 1.00x(?)
ArrayOfRef 10400 10427 +0.3% 1.00x(?)
ObjectiveCBridgeStubDateMutation 547 547 +0.0% 1.00x
DictionaryOfObjects 5158 5157 -0.0% 1.00x(?)
PopFrontArrayGeneric 9725 9711 -0.1% 1.00x(?)
PopFrontUnsafePointer 258813 258603 -0.1% 1.00x(?)
RC4 9380 9370 -0.1% 1.00x(?)
ObjectiveCBridgeStubToNSStringRef 156 156 +0.0% 1.00x
Calculator 1043 1046 +0.3% 1.00x
MapReduce 45345 45268 -0.2% 1.00x(?)
UTF8Decode 43502 43497 -0.0% 1.00x(?)
Dictionary 2127 2133 +0.3% 1.00x(?)
NopDeinit 59618 59666 +0.1% 1.00x(?)
ObjectiveCBridgeFromNSArrayAnyObject 79115 79155 +0.1% 1.00x(?)
ObjectiveCBridgeStubDataAppend 3425 3439 +0.4% 1.00x(?)
SetExclusiveOr 31519 31603 +0.3% 1.00x(?)
NSDictionaryCastToSwift 9416 9386 -0.3% 1.00x(?)
ObjectiveCBridgeStubNSDateRefAccess 1259 1260 +0.1% 1.00x(?)
ArrayInClass 3956 3954 -0.1% 1.00x(?)
ArrayOfGenericRef 10862 10840 -0.2% 1.00x(?)
ObjectiveCBridgeFromNSString 5266 5245 -0.4% 1.00x(?)
Sim2DArray 14587 14589 +0.0% 1.00x(?)
SetExclusiveOr_OfObjects 46619 46778 +0.3% 1.00x(?)
MonteCarloPi 53741 53747 +0.0% 1.00x(?)
SetUnion_OfObjects 34389 34431 +0.1% 1.00x(?)
StringHasSuffixUnicode 64938 64894 -0.1% 1.00x(?)
HashTest 5616 5616 +0.0% 1.00x
ArrayAppend 3672 3673 +0.0% 1.00x(?)
RGBHistogramOfObjects 97107 97587 +0.5% 1.00x(?)
ObjectiveCBridgeFromNSSetAnyObjectForced 7433 7450 +0.2% 1.00x(?)
ArrayAppendReserved 3567 3568 +0.0% 1.00x(?)
ArrayOfPOD 2514 2512 -0.1% 1.00x(?)
Chars 5007 5005 -0.0% 1.00x(?)
DeadArray 134364 133706 -0.5% 1.00x(?)
ArrayValueProp2 3411 3411 +0.0% 1.00x
AnyHashableWithAClass 77348 77534 +0.2% 1.00x(?)
SevenBoom 1726 1730 +0.2% 1.00x(?)
StringWalk 21103 21076 -0.1% 1.00x(?)
ObjectiveCBridgeStubFromArrayOfNSString 59177 58953 -0.4% 1.00x(?)
GlobalClass 0 0 +0.0% 1.00x
Memset 20644 20659 +0.1% 1.00x(?)
Dictionary2OfObjects 6630 6662 +0.5% 1.00x(?)
TwoSum 6682 6707 +0.4% 1.00x(?)
ObjectiveCBridgeStubNSDataAppend 2974 2966 -0.3% 1.00x(?)
ArrayValueProp3 3420 3425 +0.1% 1.00x(?)
ObjectiveCBridgeToNSString 1263 1270 +0.6% 0.99x(?)
ObjectiveCBridgeFromNSDictionaryAnyObjectToString 224167 227568 +1.5% 0.99x(?)
SortLettersInPlace 2718 2735 +0.6% 0.99x(?)
ObjectiveCBridgeFromNSDictionaryAnyObject 211807 214729 +1.4% 0.99x(?)
Dictionary3OfObjects 2298 2319 +0.9% 0.99x(?)
SuperChars 270192 272620 +0.9% 0.99x(?)
StringInterpolation 16683 16787 +0.6% 0.99x(?)
ObjectiveCBridgeStubFromNSStringRef 165 166 +0.6% 0.99x(?)
StaticArray 39807 40377 +1.4% 0.99x(?)
SetIntersect_OfObjects 13799 13966 +1.2% 0.99x
ObjectiveCBridgeToNSArray 36065 36293 +0.6% 0.99x(?)
ObjectiveCBridgeStubToNSDateRef 3342 3365 +0.7% 0.99x(?)
DictionaryLiteral 17273 17429 +0.9% 0.99x(?)
Hanoi 20344 20530 +0.9% 0.99x(?)
DictionaryRemoveOfObjects 48093 48410 +0.7% 0.99x(?)
SetIsSubsetOf 2480 2507 +1.1% 0.99x(?)
StringBuilder 3052 3071 +0.6% 0.99x(?)
SetIsSubsetOf_OfObjects 2202 2226 +1.1% 0.99x
DictionaryRemove 17325 17436 +0.6% 0.99x(?)
NSStringConversion 3424 3470 +1.3% 0.99x(?)
RGBHistogram 45838 46289 +1.0% 0.99x(?)
BitCount 103 104 +1.0% 0.99x
SortStrings 2691 2743 +1.9% 0.98x
OpenClose 434 441 +1.6% 0.98x
ObjectiveCBridgeFromNSArrayAnyObjectForced 10374 10601 +2.2% 0.98x(?)
AngryPhonebook 3391 3457 +1.9% 0.98x
StringEqualPointerComparison 9688 9842 +1.6% 0.98x
CaptureProp 114468 117013 +2.2% 0.98x
ObjectiveCBridgeStubToArrayOfNSString 34269 34957 +2.0% 0.98x(?)
SetIntersect 15436 15730 +1.9% 0.98x(?)
ObjectiveCBridgeFromNSSetAnyObjectToString 165760 169565 +2.3% 0.98x(?)
ArrayValueProp4 3320 3404 +2.5% 0.98x(?)
ObjectiveCBridgeStubFromNSDate 3798 3892 +2.5% 0.98x(?)
StrComplexWalk 8532 8814 +3.3% 0.97x
NSError 770 795 +3.2% 0.97x(?)
ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced 146421 150747 +3.0% 0.97x(?)
ObjectiveCBridgeStubDateAccess 1116 1145 +2.6% 0.97x
StringHasPrefixUnicode 15306 15737 +2.8% 0.97x
ObjectiveCBridgeStubFromNSString 818 852 +4.2% 0.96x
TypeFlood 184 194 +5.4% 0.95x(?)
ArrayOfGenericPOD 3526 3702 +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

@dabrahams
Copy link
Contributor

dabrahams commented Oct 13, 2016

This seems like the wrong fix to me. Where you wrote "Collection.map -> [A1]" above implies to me that you think an array is being constructed, but that is not the case. The operation is a lazy map that should not create any storage.

If you are seeing a speedup, I can only think of three possible explanations:

  1. The optimizer is failing badly.
  2. The Set() constructor from a Sequence does not start by using the Sequence's underestimatedCount to reserve capacity. This would be an easy thing to fix.
  3. The LazyMapCollection's underestimatedCount is, for some reason, returning the wrong value (probably zero). Easy to test for; reasonably easy to fix.

Well, it's not number 3:

  6> let a = Set(0..<3)
a: Set<Int> = {
  [0] = 2
  [1] = 0
  [2] = 1
}
  7> a.lazy.map { $0 + 1 }.underestimatedCount
$R3: Int = 3

Yeah, looks like it's number 2: https://github.com/apple/swift/blob/master/stdlib/public/core/HashedCollections.swift.gyb#L765

dabrahams pushed a commit that referenced this pull request Oct 13, 2016
@shajrawi
Copy link
Author

@dabrahams it is not 1., the Onone benchmarks exhibit the same behavior / slowdown, and are fixed by the PR, see the radar.
I just pulled in your alternate PR and tested its performance - it provides around 25% speedup over top of tree, and should be merged IMHO, but nowhere near 2X, see updated radar for new trace.

@dabrahams
Copy link
Contributor

It is a combination of 1 and 2, because there's no reason the optimizer shouldn't be able to make the code using lazy map as efficient as your code.

@JaSpa
Copy link
Contributor

JaSpa commented Oct 14, 2016

I'd guess the problem is LazyCollection has no lazy map which takes a throwing function.

@dabrahams
Copy link
Contributor

@JaSpa good call!

dabrahams pushed a commit that referenced this pull request Oct 19, 2016
@dabrahams
Copy link
Contributor

I guess we have to take this fix, then, but we need more-general solutions to the problems of

  1. picking up the non-lazy map (https://bugs.swift.org/browse/SR-2990)
  2. having no way to propagate errors through lazy collections (https://bugs.swift.org/browse/SR-2991)

@dabrahams dabrahams merged commit 22f5dfa into swiftlang:master Oct 19, 2016
@shajrawi shajrawi deleted the idasany_perf branch October 19, 2016 19:45
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.

5 participants