[stdlib] Remove _buffer requirement from ArrayType

Until we get an optimizer pass to remove get/set pairs, passing a
property that is a protocol requirement as inout from generic code is
always going to cause an extra retain, causing many unintended Array
copies.

Because this dropped reference counts to 1 in some cases, it exercised
previously-untested code paths and uncovered bugs, particularly in the
handling of subrange replacement on Slice<T>.

There are still differences in speed for short arrays of CGPoint that bear
investigation, but at least as things scale up, the ratio of time goes
to 1.

Fixes <rdar://problem/17040913> append and += on an array have
completely different performance

Swift SVN r19228
This commit is contained in:
Dave Abrahams
2014-06-26 08:54:07 +00:00
parent 321d608935
commit 1fb11d623b
6 changed files with 253 additions and 125 deletions

View File

@@ -134,6 +134,18 @@ let emptyNSSwiftArray : _NSSwiftArray
return self
}
/// Replace the given subRange with the first newCount elements of
/// the given collection.
///
/// Requires: this buffer is backed by a uniquely-referenced
/// ContiguousArrayBuffer
@public
mutating func replace<C: Collection where C.GeneratorType.Element == Element>(
#subRange: Range<Int>, with newCount: Int, elementsOf newValues: C
) {
_arrayNonSliceInPlaceReplace(&self, subRange, newCount, newValues)
}
/// Get/set the value of the ith element
@public subscript(i: Int) -> T {
get {