[stdlib] add two-operand version of max and use max2 in stdlib when appropriate.

This helps array append's performance by ~ 2x. The generic max with a variadic
argument creates a temporary array then iterates over the array.

rdar://17140639 rdar://17073827


Swift SVN r18764
This commit is contained in:
Manman Ren
2014-06-09 23:56:40 +00:00
parent c8ac91e4c7
commit cc90c81239
6 changed files with 16 additions and 8 deletions

View File

@@ -312,6 +312,14 @@ func min<T : Comparable>(x: T, y: T, rest: T...) -> T {
return r
}
func max2<T : Comparable>(x: T, y: T) -> T {
var r = y
if y < x {
r = x
}
return r
}
func max<T : Comparable>(x: T, y: T, rest: T...) -> T {
var r = y
if y < x {

View File

@@ -507,7 +507,7 @@ where C.GeneratorType.Element == A._Buffer.Element
// Ensure uniqueness, mutability, and sufficient storage. Note that
// for consistency, we need unique lhs even if rhs is empty.
lhs.reserveCapacity(
newCount > capacity ? max(newCount, capacity * 2) : newCount)
newCount > capacity ? max2(newCount, capacity * 2) : newCount)
var p = lhs._buffer.elementStorage + oldCount
for x in rhs {
@@ -541,14 +541,14 @@ func _demandUniqueMutableBuffer<_Buffer: ArrayBufferType>(
_sanityCheck(newCount >= 0)
let requiredCapacity = max(newCount, minimumCapacity)
let requiredCapacity = max2(newCount, minimumCapacity)
if let b = source.requestUniqueMutableBuffer(requiredCapacity) {
source.count = newCount
return nil
}
let minimumCapacity = max(
let minimumCapacity = max2(
requiredCapacity,
newCount > source.capacity ? source.capacity * 2 : source.capacity)

View File

@@ -57,7 +57,7 @@ struct ContiguousArrayBuffer<T> : ArrayBufferType, LogicValue {
_base = HeapBuffer(
ContiguousArrayStorage<T>.self,
_ArrayBody(),
max(count, minimumCapacity))
max2(count, minimumCapacity))
var bridged = false
if _canBeClass(T.self) {

View File

@@ -405,7 +405,7 @@ struct _NativeDictionaryStorage<KeyType : Hashable, ValueType> :
static func getMinCapacity(
requestedCount: Int, _ maxLoadFactorInverse: Double) -> Int {
// `requestedCount + 1` below ensures that we don't fill in the last hole
return max(Int(Double(requestedCount) * maxLoadFactorInverse),
return max2(Int(Double(requestedCount) * maxLoadFactorInverse),
requestedCount + 1)
}

View File

@@ -90,7 +90,7 @@ struct _StringBuffer {
// Allocate storage
self = _StringBuffer(
capacity: max(utf16Count, minimumCapacity),
capacity: max2(utf16Count, minimumCapacity),
initialSize: utf16Count,
elementWidth: isAscii ? 1 : 2)

View File

@@ -339,7 +339,7 @@ struct _StringCore {
}
else if newSize > buffer.capacity {
// Growth failed because of insufficient storage; double the size
return (max(buffer.capacity * 2, newSize), .null())
return (max2(buffer.capacity * 2, newSize), .null())
}
}
return (newSize, .null())