mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
* Don't allocate breadrumbs pointer if under threshold * Increase breadrumbs threshold * Linear 16-byte bucketing until 128 bytes, malloc_size after * Allow cap less than _SmallString.capacity (bridging non-ASCII) This change decreases the amount of heap usage for moderate-length strings (< 64 UTF-8 code units in length) and increases the amount of spare code unit capacity available (less growth needed). Average improvements for moderate-length strings: * 64-bit: on average, 8 bytes saved and 4 bytes of extra capacity * 32-bit: on average, 4 bytes saved and 6 bytes of extra capacity Additionally, on 32-bit, large-length strings also gain an average of 6 bytes of extra spare capacity. Details: On 64-bit, half of moderate-length allocations will save 16 bytes while the other half get an extra 8 bytes of spare capacity. On 32-bit, a quarter of moderate-length allocations will save 16 bytes, and the rest get an extra 4 bytes of spare capacity. Additionally, 32-bit string's storage class now claims its full allocation, which is its birthright. Prior to this change, we'd have on average 1.5 bytes of spare capacity, and now we have 7.5 bytes of spare capacity. Breadcrumbs threshold is increased from the super-conservative 32 to the pretty-conservative 64. Some speed improvements are incorporated in this change, but more are in flight. Even without those eventual improvements, this is a worthwhile change (ASCII is still fast-pathed and irrelevant to breadcrumbing). For a complex real-world workload, this amounts to around a 5% improvement to transient heap usage due to all strings and a 4% improvement to peak heap usage due to all strings. For moderate-length strings specifically, this gives around 11% improvement to both.
90 lines
2.8 KiB
Swift
90 lines
2.8 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// This file contains non-API (or underscored) declarations that are needed to
|
|
// be kept around for ABI compatibility
|
|
|
|
extension Unicode.UTF16 {
|
|
@available(*, unavailable, renamed: "Unicode.UTF16.isASCII")
|
|
@inlinable
|
|
public static func _isASCII(_ x: CodeUnit) -> Bool {
|
|
return Unicode.UTF16.isASCII(x)
|
|
}
|
|
}
|
|
|
|
@available(*, unavailable, renamed: "Unicode.UTF8.isASCII")
|
|
@inlinable
|
|
internal func _isASCII(_ x: UInt8) -> Bool {
|
|
return Unicode.UTF8.isASCII(x)
|
|
}
|
|
|
|
@available(*, unavailable, renamed: "Unicode.UTF8.isContinuation")
|
|
@inlinable
|
|
internal func _isContinuation(_ x: UInt8) -> Bool {
|
|
return UTF8.isContinuation(x)
|
|
}
|
|
|
|
extension Substring {
|
|
@available(*, unavailable, renamed: "Substring.base")
|
|
@inlinable
|
|
internal var _wholeString: String { return base }
|
|
}
|
|
|
|
extension String {
|
|
@available(*, unavailable, renamed: "String.withUTF8")
|
|
@inlinable
|
|
internal func _withUTF8<R>(
|
|
_ body: (UnsafeBufferPointer<UInt8>) throws -> R
|
|
) rethrows -> R {
|
|
var copy = self
|
|
return try copy.withUTF8(body)
|
|
}
|
|
}
|
|
|
|
extension Substring {
|
|
@available(*, unavailable, renamed: "Substring.withUTF8")
|
|
@inlinable
|
|
internal func _withUTF8<R>(
|
|
_ body: (UnsafeBufferPointer<UInt8>) throws -> R
|
|
) rethrows -> R {
|
|
var copy = self
|
|
return try copy.withUTF8(body)
|
|
}
|
|
}
|
|
|
|
// This function is no longer used but must be kept for ABI compatibility
|
|
// because references to it may have been inlined.
|
|
@usableFromInline
|
|
internal func _branchHint(_ actual: Bool, expected: Bool) -> Bool {
|
|
// The LLVM intrinsic underlying int_expect_Int1 now requires an immediate
|
|
// argument for the expected value so we cannot call it here. This should
|
|
// never be called in cases where performance matters, so just return the
|
|
// value without any branch hint.
|
|
return actual
|
|
}
|
|
|
|
extension String {
|
|
@usableFromInline // Never actually used in inlinable code...
|
|
internal func _nativeCopyUTF16CodeUnits(
|
|
into buffer: UnsafeMutableBufferPointer<UInt16>,
|
|
range: Range<String.Index>
|
|
) { fatalError() }
|
|
}
|
|
|
|
extension String.UTF16View {
|
|
// Swift 5.x: This was accidentally shipped as inlinable, but was never used
|
|
// from an inlinable context. The definition is kept around for techincal ABI
|
|
// compatibility (even though it shouldn't matter), but is unused.
|
|
@inlinable @inline(__always)
|
|
internal var _shortHeuristic: Int { return 32 }
|
|
}
|