[swift-evolution] [Pitch] Normalize Slice Types for Unsafe Buffers

Ben Cohen ben_cohen at apple.com
Thu Dec 8 14:31:52 CST 2016


> On Dec 2, 2016, at 8:27 PM, Nate Cook <natecook at gmail.com> wrote:
> 
>> On Dec 2, 2016, at 2:12 PM, Ben Cohen via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>>> On Dec 1, 2016, at 11:33 PM, Nate Cook via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> 3) Make all buffer pointers their own slices but use a different index type. If the indices were just wrapped pointers, that would handle the index sharing without needing an additional property on the buffer. We could also maintain integer-based stridable conformance (which greatly simplifies index arithmetic), since the indices would just offset by a byte for raw buffers or a stride for typed buffers.
>>> 
>> 
>> Unfortunately, switching to non-integer indices would change this from being mildly source-breaking to being extremely source-breaking, as there’s lots of code out there using buffers today indexing them with integers (including integer literals).
>> 
>> The big win with UnsafeBufferPointer having an integer index is it’s a drop-in replacement for arrays, so when you hit a performance problem using an array you can quickly switch to using a buffer under most circumstances instead without having to change much of your code – including code that uses for i in 0..<myArray.count, of which there is a lot out there in the wild. Switching to an opaque index would break anyone doing that.
> 
> It is definitely very source-breaking, though with relatively simple fixits:
> 
> 	buf[0] ---> buf[buf.startIndex]
> 	buf[3] ---> buf[buf.startIndex + 3]
> 	buf[i] ---> buf[buf.startIndex + i]
> 
> Any integer arithmetic happening outside the subscript could be left unchanged. If that cost isn't worth the benefit, then making UnsafeRawBufferPointer use Slice as its slice type is probably the best way to resolve that issue.
> 
> Nate



The fixits aren’t quite that simple for slices, though:

	let slice = buf[3..<6]
	slice[3] —> slice[slice.startIndex + 0] // fixit would somehow need to know this is 0 not 3
	slice[i] —> slice[slice.startIndex + ??] // or even need to know this is, erm, I haven’t had enough coffee this morning

The other downside is it would thwart speculatively switching an Array to an UnsafeBuffer to see if that was a bottleneck, then switching back.

> On Dec 1, 2016, at 11:33 PM, Nate Cook via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 1) Switch to using Slice as a wrapper for UnsafeRawBufferPointer.
> 

Based on the above, it seems like this is the least bad option, and we need to do this ASAP as currently UnsafeRawBufferPointer is non-compliant with the requirements of slicing and needs changing before it’s more widely adopted.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161208/e85f7af4/attachment.html>


More information about the swift-evolution mailing list