Skip to content

Refactors internal func _applyMapping using _FixedArray16 #31333

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

Conversation

valeriyvan
Copy link
Contributor

Refactors internal func _applyMapping using _FixedArray16.
Addresses TODO.

@theblixguy theblixguy requested a review from milseman May 4, 2020 18:21
Copy link
Member

@natecook1000 natecook1000 left a comment

Choose a reason for hiding this comment

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

Thanks for working on addressing this TODO @valeriyvan! I have some notes below — you might want to look at rebinding the memory inside your first array.withUnsafeMutableBufferPointer and then doing all the work inside that one closure.

return array[..<len].withUnsafeBufferPointer {
return String._uncheckedFromUTF16($0)
return array.withUnsafeBufferPointer { (bufPtr: UnsafeBufferPointer<UInt64>) -> String in
return UnsafeBufferPointer(rebasing: bufPtr[..<len]).withMemoryRebound(to: UInt16.self) {
Copy link
Member

Choose a reason for hiding this comment

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

From my reading, len is the UInt16 count, but it's being used here with the UInt64 storage. Do I have that backwards?

In addition, withMemoryRebound prohibits changing the size of the bound type, so this isn't a legal call. See https://developer.apple.com/documentation/swift/unsafebufferpointer/2950055-withmemoryrebound

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@valeriyvan valeriyvan requested a review from natecook1000 May 11, 2020 16:16
@natecook1000
Copy link
Member

@swift-ci Please smoke test

return _scalar.withUTF16CodeUnits { utf16 in
var array = _FixedArray16<UInt64>(allZeros: ()) // 16 * UInt64 take 128 bytes, same as 64 * UInt16
let string: String = array.withUnsafeMutableBufferPointer { bufPtrUInt64 in
let bufPtrUInt16: UnsafeMutablePointer<UInt16> = UnsafeMutableRawPointer(bufPtrUInt64.baseAddress._unsafelyUnwrappedUnchecked)

This comment was marked as outdated.

@@ -692,15 +692,16 @@ extension Unicode.Scalar.Properties {
/// all current case mappings. In the event more space is needed, it will be
/// allocated on the heap.
Copy link
Collaborator

@xwu xwu May 24, 2020

Choose a reason for hiding this comment

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

This doc comment doesn't match the implementation proposed in this PR.

IIUC, a buffer capable of holding 64 code units is allocated on the stack with this change instead of the heap, whereas as originally intended (but not implemented) only 16 code units would have been allocated on the stack, falling back to a larger heap allocation if needed.

I think perhaps instead what the original author had in mind to complete the TODO was as follows (typed freehand; check wellformedness with compiler):

internal func _applyMapping(_ u_strTo: _U_StrToX) -> String {
  // Allocate 16 code units on the stack.
  var fixedArray = _FixedArray16<UInt16>(allZeros: ())
  let count: Int = fixedArray.withUnsafeMutableBufferPointer { bufPtr in
    return _scalar.withUTF16CodeUnits { utf16 in
      var err = __swift_stdlib_U_ZERO_ERROR
      let correctSize = u_strTo(
        bufPtr.baseAddress._unsafelyUnwrappedUnchecked,
        Int32(bufPtr.count),
        utf16.baseAddress._unsafelyUnwrappedUnchecked,
        Int32(utf16.count),
        "",
        &err)
      guard err.isSuccess else {
        fatalError("Unexpected error case-converting Unicode scalar.")
      }
      return Int(correctSize)
    }
  }
  if _fastPath(count <= 16) {
    fixedArray.count = count
    return fixedArray.withUnsafeBufferPointer {
      return String._uncheckedFromUTF16($0)
    }
  }
  // Allocate `count` code units on the heap.
  var array = Array<UInt16>(repeating: 0, count: count)
  array.withUnsafeMutableBufferPointer { bufPtr in
    _scalar.withUTF16CodeUnits { utf16 in
      var err = __swift_stdlib_U_ZERO_ERROR
      let correctSize = u_strTo(
        bufPtr.baseAddress._unsafelyUnwrappedUnchecked,
        Int32(bufPtr.count),
        utf16.baseAddress._unsafelyUnwrappedUnchecked,
        Int32(utf16.count),
        "",
        &err)
      guard err.isSuccess else {
        fatalError("Unexpected error case-converting Unicode scalar.")
      }
      _internalInvariant(count == correctSize, "inconsistent ICU behavior")
    }
  }
  return array.withUnsafeBufferPointer {
    return String._uncheckedFromUTF16($0)
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That absolutely makes sense. I've changed a little the second part.

@valeriyvan valeriyvan requested a review from xwu May 25, 2020 15:54
@xwu xwu requested a review from natecook1000 May 25, 2020 21:06
@xwu
Copy link
Collaborator

xwu commented May 25, 2020

@valeriyvan Great; if you wouldn't mind squashing these commits into one (git rebase -i HEAD~5 and mark the last four commits as fix-ups), we can kick off some testing, and see if @natecook1000 approves!

@valeriyvan valeriyvan force-pushed the _applyMappingUnicodeScalarProperties branch from cd36f63 to c7fc0d8 Compare May 25, 2020 23:58
@valeriyvan valeriyvan force-pushed the _applyMappingUnicodeScalarProperties branch from c7fc0d8 to b5392e8 Compare May 26, 2020 00:00
@xwu
Copy link
Collaborator

xwu commented May 26, 2020

@swift-ci test

@swift-ci

This comment has been minimized.

@swift-ci

This comment has been minimized.

@natecook1000
Copy link
Member

Thanks for the review, @xwu! LGTM.

@swift-ci Please smoke benchmark

@natecook1000
Copy link
Member

@swift-ci Please smoke benchmark

@swift-ci
Copy link
Contributor

Performance: -O

Regression OLD NEW DELTA RATIO
EqualSubstringSubstring 22 30 +36.4% 0.73x
LessSubstringSubstring 22 30 +36.4% 0.73x
EqualSubstringSubstringGenericEquatable 22 30 +36.4% 0.73x
EqualSubstringString 22 30 +36.4% 0.73x
LessSubstringSubstringGenericComparable 22 30 +36.4% 0.73x
EqualStringSubstring 23 30 +30.4% 0.77x
UTF8Decode_InitFromCustom_contiguous 143 167 +16.8% 0.86x
UTF8Decode_InitDecoding 143 164 +14.7% 0.87x
StringComparison_longSharedPrefix 321 357 +11.2% 0.90x (?)
AngryPhonebook.Strasse 145 158 +9.0% 0.92x (?)
AngryPhonebook.Armenian 160 173 +8.1% 0.92x (?)
AngryPhonebook.Cyrillic 172 185 +7.6% 0.93x (?)
 
Improvement OLD NEW DELTA RATIO
Data.hash.Medium 34 30 -11.8% 1.13x (?)
Set.isDisjoint.Int100 128 119 -7.0% 1.08x (?)

Code size: -O

Performance: -Osize

Regression OLD NEW DELTA RATIO
EqualSubstringSubstring 22 30 +36.4% 0.73x
EqualSubstringSubstringGenericEquatable 22 30 +36.4% 0.73x
EqualSubstringString 22 30 +36.4% 0.73x
LessSubstringSubstring 23 30 +30.4% 0.77x
EqualStringSubstring 23 30 +30.4% 0.77x
LessSubstringSubstringGenericComparable 23 30 +30.4% 0.77x
UTF8Decode_InitFromCustom_contiguous 143 164 +14.7% 0.87x (?)
UTF8Decode_InitDecoding 143 163 +14.0% 0.88x (?)
StringComparison_longSharedPrefix 323 359 +11.1% 0.90x (?)
AngryPhonebook.Strasse 144 158 +9.7% 0.91x (?)
AngryPhonebook.Cyrillic 171 185 +8.2% 0.92x (?)
AngryPhonebook.Armenian 160 173 +8.1% 0.92x (?)
UTF8Decode_InitFromCustom_noncontiguous 267 288 +7.9% 0.93x (?)
 
Improvement OLD NEW DELTA RATIO
Data.hash.Medium 34 30 -11.8% 1.13x
StringHasPrefixAscii 1320 1200 -9.1% 1.10x (?)
StringHasSuffixAscii 1430 1320 -7.7% 1.08x (?)

Code size: -Osize

Performance: -Onone

Regression OLD NEW DELTA RATIO
EqualSubstringString 27 35 +29.6% 0.77x
EqualSubstringSubstring 27 34 +25.9% 0.79x (?)
LessSubstringSubstring 27 34 +25.9% 0.79x
EqualSubstringSubstringGenericEquatable 27 34 +25.9% 0.79x
LessSubstringSubstringGenericComparable 27 34 +25.9% 0.79x
EqualStringSubstring 28 35 +25.0% 0.80x (?)
UTF8Decode_InitDecoding 151 174 +15.2% 0.87x (?)
UTF8Decode_InitFromCustom_contiguous 155 177 +14.2% 0.88x
 
Improvement OLD NEW DELTA RATIO
Data.hash.Medium 39 35 -10.3% 1.11x (?)

Code size: -swiftlibs

How to read the data The tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.

If you see any unexpected regressions, you should consider fixing the
regressions before you merge the PR.

Noise: Sometimes the performance results (not code size!) contain false
alarms. Unexpected regressions which are marked with '(?)' are probably noise.
If you see regressions which you cannot explain you can try to run the
benchmarks again. If regressions still show up, please consult with the
performance team (@eeckstein).

Hardware Overview
  Model Name: Mac mini
  Model Identifier: Macmini8,1
  Processor Name: 6-Core Intel Core i7
  Processor Speed: 3.2 GHz
  Number of Processors: 1
  Total Number of Cores: 6
  L2 Cache (per Core): 256 KB
  L3 Cache: 12 MB
  Memory: 64 GB

@natecook1000
Copy link
Member

@swift-ci Please benchmark

@swift-ci
Copy link
Contributor

Performance: -O

Improvement OLD NEW DELTA RATIO
EqualSubstringSubstring 44 40 -9.1% 1.10x (?)
LessSubstringSubstring 44 40 -9.1% 1.10x
EqualSubstringSubstringGenericEquatable 44 40 -9.1% 1.10x (?)
EqualSubstringString 44 40 -9.1% 1.10x
LessSubstringSubstringGenericComparable 44 40 -9.1% 1.10x (?)
EqualStringSubstring 45 41 -8.9% 1.10x (?)
ObjectiveCBridgeStubToNSDate2 590 550 -6.8% 1.07x (?)

Code size: -O

Performance: -Osize

Improvement OLD NEW DELTA RATIO
String.data.LargeUnicode 121 108 -10.7% 1.12x (?)
EqualSubstringSubstring 44 40 -9.1% 1.10x (?)
EqualSubstringSubstringGenericEquatable 44 40 -9.1% 1.10x
EqualSubstringString 44 40 -9.1% 1.10x
LessSubstringSubstring 45 41 -8.9% 1.10x
EqualStringSubstring 45 41 -8.9% 1.10x (?)
LessSubstringSubstringGenericComparable 45 41 -8.9% 1.10x
ObjectiveCBridgeStubFromArrayOfNSString2 3050 2840 -6.9% 1.07x (?)

Code size: -Osize

Performance: -Onone

Regression OLD NEW DELTA RATIO
StringToDataEmpty 1600 2100 +31.2% 0.76x (?)
StringToDataSmall 1750 2250 +28.6% 0.78x (?)
 
Improvement OLD NEW DELTA RATIO
LessSubstringSubstringGenericComparable 51 47 -7.8% 1.09x

Code size: -swiftlibs

How to read the data The tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.

If you see any unexpected regressions, you should consider fixing the
regressions before you merge the PR.

Noise: Sometimes the performance results (not code size!) contain false
alarms. Unexpected regressions which are marked with '(?)' are probably noise.
If you see regressions which you cannot explain you can try to run the
benchmarks again. If regressions still show up, please consult with the
performance team (@eeckstein).

Hardware Overview
  Model Name: Mac Pro
  Model Identifier: MacPro6,1
  Processor Name: 12-Core Intel Xeon E5
  Processor Speed: 2.7 GHz
  Number of Processors: 1
  Total Number of Cores: 12
  L2 Cache (per Core): 256 KB
  L3 Cache: 30 MB
  Memory: 64 GB

@natecook1000
Copy link
Member

@swift-ci Please benchmark

@swift-ci
Copy link
Contributor

Performance: -O

Regression OLD NEW DELTA RATIO
ParseFloat.Float.Exp 9 10 +11.1% 0.90x (?)
StringHasPrefixAscii 1280 1390 +8.6% 0.92x (?)
 
Improvement OLD NEW DELTA RATIO
EqualSubstringSubstring 30 22 -26.7% 1.36x
LessSubstringSubstring 30 22 -26.7% 1.36x
EqualSubstringSubstringGenericEquatable 30 22 -26.7% 1.36x
EqualSubstringString 30 22 -26.7% 1.36x
EqualStringSubstring 30 23 -23.3% 1.30x
LessSubstringSubstringGenericComparable 30 23 -23.3% 1.30x (?)
StringComparison_longSharedPrefix 358 321 -10.3% 1.12x (?)
AngryPhonebook.Strasse 150 137 -8.7% 1.09x (?)
AngryPhonebook.Cyrillic 183 168 -8.2% 1.09x (?)
AngryPhonebook.Armenian 171 157 -8.2% 1.09x (?)

Code size: -O

Performance: -Osize

Regression OLD NEW DELTA RATIO
FlattenListFlatMap 3835 4502 +17.4% 0.85x (?)
StringHasPrefixAscii 1170 1330 +13.7% 0.88x (?)
FlattenListLoop 2928 3219 +9.9% 0.91x (?)
AngryPhonebook 252 273 +8.3% 0.92x (?)
 
Improvement OLD NEW DELTA RATIO
EqualSubstringSubstring 30 22 -26.7% 1.36x
EqualSubstringSubstringGenericEquatable 30 22 -26.7% 1.36x
EqualSubstringString 30 22 -26.7% 1.36x
LessSubstringSubstring 30 23 -23.3% 1.30x
EqualStringSubstring 30 23 -23.3% 1.30x
LessSubstringSubstringGenericComparable 30 23 -23.3% 1.30x
StringComparison_longSharedPrefix 359 323 -10.0% 1.11x (?)
StringBuilderSmallReservingCapacity 223 202 -9.4% 1.10x (?)
AngryPhonebook.Strasse 150 137 -8.7% 1.09x (?)
AngryPhonebook.Armenian 171 157 -8.2% 1.09x (?)
AngryPhonebook.Cyrillic 183 169 -7.7% 1.08x (?)

Code size: -Osize

Performance: -Onone

Improvement OLD NEW DELTA RATIO
LessSubstringSubstring 35 27 -22.9% 1.30x (?)
EqualSubstringSubstring 34 27 -20.6% 1.26x (?)
EqualSubstringSubstringGenericEquatable 34 27 -20.6% 1.26x
LessSubstringSubstringGenericComparable 34 27 -20.6% 1.26x
EqualStringSubstring 35 28 -20.0% 1.25x (?)
EqualSubstringString 34 28 -17.6% 1.21x (?)
AngryPhonebook.Strasse 151 137 -9.3% 1.10x (?)
AngryPhonebook.Cyrillic 183 168 -8.2% 1.09x (?)
AngryPhonebook.Armenian 171 157 -8.2% 1.09x (?)

Code size: -swiftlibs

How to read the data The tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.

If you see any unexpected regressions, you should consider fixing the
regressions before you merge the PR.

Noise: Sometimes the performance results (not code size!) contain false
alarms. Unexpected regressions which are marked with '(?)' are probably noise.
If you see regressions which you cannot explain you can try to run the
benchmarks again. If regressions still show up, please consult with the
performance team (@eeckstein).

Hardware Overview
  Model Name: Mac mini
  Model Identifier: Macmini8,1
  Processor Name: 6-Core Intel Core i7
  Processor Speed: 3.2 GHz
  Number of Processors: 1
  Total Number of Cores: 6
  L2 Cache (per Core): 256 KB
  L3 Cache: 12 MB
  Memory: 64 GB

@natecook1000
Copy link
Member

@swift-ci Please smoke test and merge

@xwu xwu merged commit a99d7ea into swiftlang:master Jun 4, 2020
@valeriyvan valeriyvan deleted the _applyMappingUnicodeScalarProperties branch February 20, 2023 08:11
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.

None yet

4 participants