Re: [swift-users] Passing value types or members of value types?

2017-05-06 Thread Brent Royal-Gordon via swift-users
> On May 6, 2017, at 9:33 PM, Kelvin Ma via swift-users  
> wrote:
> 
> If I have a “large” struct like
> 
> struct Vertex
> {
> let x:Double, y:Double
> var r:Int, g:Int, b:Int
> let s:Double, t:Double
> var selected:Bool
> }
> 
> and I want to pass it to a function without modifying it like
> 
> func taxicab_distance(_ v1:Vertex, _ v2:Vertex) -> Double
> {
> return v2.x - v1.x + v2.y - v1.y
> }
> 
> Will the entire struct Vertex get copied and pushed onto the stack, or will 
> only the relevant members be passed to the function?
> 
> In other words, does the compiler know to optimize this call down to
> 
> func taxicab_distance(v2x:Double, v1x:Double, v2y:Double, v1y:Double) -> 
> Double
> {
> return v2x - v1x + v2y - v1y
> }

When passed as an argument, a struct is recursively broken up into individual 
primitives, and each of those is passed in separate arguments. (The primitive 
types in question are mostly special "builtin" types which are wrapped by 
standard library types like `Int` and `Double`.) As far as I'm aware, there is 
no optimization that removes unused parts of the struct. That means this would 
be passed as something like:

func taxicab_distance(_ v1.x._value: Builtin.Float64, _ v1.y._value: 
Builtin.Float64, _ v1.r._value: Builtin.Int64, _ v1.g._value: Builtin.Int64, _ 
v1.b._value: Builtin.Int64, _ v1.s._value: Builtin.Float64, _ v1.t._value: 
Builtin.Float64, _ v1.selected._value: Builtin.Int1, _ v2.x._value: 
Builtin.Float64, _ v2.y._value: Builtin.Float64, _ v2.r._value: Builtin.Int64, 
_ v2.g._value: Builtin.Int64, _ v2.b._value: Builtin.Int64, _ v2.s._value: 
Builtin.Float64, _ v2.t._value: Builtin.Float64, _ v2.selected._value: 
Builtin.Int1) -> Builtin.Float64 { … }

Because of this, it may sometimes make sense to convert large structs into 
copy-on-write types by hand—basically, make a struct which wraps an inner class 
type, guarding all mutations with an `isUniquelyReferenced(_:)` check. (You're 
right that there's no implicit copy-on-write behavior in structs currently—when 
a struct has copy-on-write behavior, it has been manually implemented that way.)

Note that this may not always be the case: There's a built-in copy-on-write 
optimization which will soon come to instances which have been cast to a 
protocol type, and the "resilient" structs planned for a future version of 
Swift will probably be passed by reference in some way. But I believe that's 
the state of things in Swift 3.

-- 
Brent Royal-Gordon
Architechies

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Passing value types or members of value types?

2017-05-06 Thread Daniel Dunbar via swift-users

> On May 6, 2017, at 10:27 PM, Nate Birkholz via swift-users 
>  wrote:
> 
> Classes and structs are different things. Classes are passed by reference, 
> structs are passed by value with copy on write. 

This is not correct. Array, and other types, implement copy-on-write 
themselves, but this is not true of arbitrary structs.

To answer Kelvin's question, yes, the optimizer will be able to see through 
that code _assuming_ it can see the definition in a way it can optimize 
(generally speaking, this means not something which will be dynamically 
dispatched, and where the implementation is available (i.e. the same file, or 
the same module with whole module optimization enabled)).

You can verify this by simply writing a small sample program and spot checking 
the assembly matches what you want, for example:
--
$ cat z.swift 
struct Vertex {
let x: Double, y: Double
var r:Int, g:Int, b:Int
let s:Double, t:Double
var selected:Bool
}

private func taxicab_distance(_ v1:Vertex, _ v2:Vertex) -> Double {
return v2.x - v1.x + v2.y - v1.y
}

func f0(a: Vertex, b: Vertex) -> Double {
  return taxicab_distance(a, b)
}

$ swiftc -Ounchecked -S -o - z.swift | grep 'main2f0' -A8
.private_extern __T04main2f0SdAA6VertexV1a_AD1btF
.globl  __T04main2f0SdAA6VertexV1a_AD1btF
.p2align4, 0x90
__T04main2f0SdAA6VertexV1a_AD1btF:
pushq   %rbp
movq%rsp, %rbp
movsd   (%rsi), %xmm0
subsd   (%rdi), %xmm0
addsd   8(%rsi), %xmm0
subsd   8(%rdi), %xmm0
popq%rbp
retq
--

 - Daniel


> 
> Strings and Arrays are structs, not classes.
> 
> On Sat, May 6, 2017 at 10:24 PM, Kelvin Ma  > wrote:
> I hear that a lot but why do all the official sources sound like 
> copy-on-write is something you have to manually implement with a class and 
> isUniquelyReferenced if it’s not an array or a string?
> 
> On May 7, 2017, at 12:02 AM, Nate Birkholz  > wrote:
> 
>> Let me try one more time, my stupid phone keeps changing words. 
>> 
>> ACTUALLY, the struct is a pointer until it's written to, and is only copied 
>> on write.
>> 
>> Sent from my iPhone, please excuse brevity and errors
>> 
>> On May 6, 2017, at 9:59 PM, Nate Birkholz > > wrote:
>> 
>>> Oddly, until it's *written* you will be working with a pointer.
>>> 
>>> Sent from my iPhone, please excuse brevity and errors
>>> 
>>> On May 6, 2017, at 9:33 PM, Kelvin Ma via swift-users 
>>> > wrote:
>>> 
 If I have a “large” struct like
 
 struct Vertex
 {
 let x:Double, y:Double
 var r:Int, g:Int, b:Int
 let s:Double, t:Double
 var selected:Bool
 }
 
 and I want to pass it to a function without modifying it like
 
 func taxicab_distance(_ v1:Vertex, _ v2:Vertex) -> Double
 {
 return v2.x - v1.x + v2.y - v1.y
 }
 
 Will the entire struct Vertex get copied and pushed onto the stack, or 
 will only the relevant members be passed to the function?
 
 In other words, does the compiler know to optimize this call down to
 
 func taxicab_distance(v2x:Double, v1x:Double, v2y:Double, v1y:Double) -> 
 Double
 {
 return v2x - v1x + v2y - v1y
 }
 
 ?
 ___
 swift-users mailing list
 swift-users@swift.org 
 https://lists.swift.org/mailman/listinfo/swift-users 
 
> 
> 
> 
> -- 
> Nate Birkholz
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Passing value types or members of value types?

2017-05-06 Thread Nate Birkholz via swift-users
Classes and structs are different things. Classes are passed by reference,
structs are passed by value with copy on write.

Strings and Arrays are structs, not classes.

On Sat, May 6, 2017 at 10:24 PM, Kelvin Ma  wrote:

> I hear that a lot but why do all the official sources sound like
> copy-on-write is something you have to manually implement with a class and
> isUniquelyReferenced if it’s not an array or a string?
>
> On May 7, 2017, at 12:02 AM, Nate Birkholz  wrote:
>
> Let me try one more time, my stupid phone keeps changing words.
>
> ACTUALLY, the struct is a pointer until it's written to, and is only
> copied on write.
>
> Sent from my iPhone, please excuse brevity and errors
>
> On May 6, 2017, at 9:59 PM, Nate Birkholz  wrote:
>
> Oddly, until it's *written* you will be working with a pointer.
>
> Sent from my iPhone, please excuse brevity and errors
>
> On May 6, 2017, at 9:33 PM, Kelvin Ma via swift-users <
> swift-users@swift.org> wrote:
>
> If I have a “large” struct like
>
> struct Vertex
> {
> let x:Double, y:Double
> var r:Int, g:Int, b:Int
> let s:Double, t:Double
> var selected:Bool
> }
>
> and I want to pass it to a function without modifying it like
>
> func taxicab_distance(_ v1:Vertex, _ v2:Vertex) -> Double
> {
> return v2.x - v1.x + v2.y - v1.y
> }
>
> Will the entire struct Vertex get copied and pushed onto the stack, or
> will only the relevant members be passed to the function?
>
> In other words, does the compiler know to optimize this call down to
>
> func taxicab_distance(v2x:Double, v1x:Double, v2y:Double, v1y:Double) ->
> Double
> {
> return v2x - v1x + v2y - v1y
> }
>
> ?
>
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>


-- 
Nate Birkholz
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Passing value types or members of value types?

2017-05-06 Thread Kelvin Ma via swift-users
I hear that a lot but why do all the official sources sound like copy-on-write 
is something you have to manually implement with a class and 
isUniquelyReferenced if it’s not an array or a string?

> On May 7, 2017, at 12:02 AM, Nate Birkholz  wrote:
> 
> Let me try one more time, my stupid phone keeps changing words. 
> 
> ACTUALLY, the struct is a pointer until it's written to, and is only copied 
> on write.
> 
> Sent from my iPhone, please excuse brevity and errors
> 
>> On May 6, 2017, at 9:59 PM, Nate Birkholz  wrote:
>> 
>> Oddly, until it's *written* you will be working with a pointer.
>> 
>> Sent from my iPhone, please excuse brevity and errors
>> 
>>> On May 6, 2017, at 9:33 PM, Kelvin Ma via swift-users 
>>>  wrote:
>>> 
>>> If I have a “large” struct like
>>> 
>>> struct Vertex
>>> {
>>> let x:Double, y:Double
>>> var r:Int, g:Int, b:Int
>>> let s:Double, t:Double
>>> var selected:Bool
>>> }
>>> 
>>> and I want to pass it to a function without modifying it like
>>> 
>>> func taxicab_distance(_ v1:Vertex, _ v2:Vertex) -> Double
>>> {
>>> return v2.x - v1.x + v2.y - v1.y
>>> }
>>> 
>>> Will the entire struct Vertex get copied and pushed onto the stack, or will 
>>> only the relevant members be passed to the function?
>>> 
>>> In other words, does the compiler know to optimize this call down to
>>> 
>>> func taxicab_distance(v2x:Double, v1x:Double, v2y:Double, v1y:Double) -> 
>>> Double
>>> {
>>> return v2x - v1x + v2y - v1y
>>> }
>>> 
>>> ?
>>> ___
>>> swift-users mailing list
>>> swift-users@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


[swift-users] Passing value types or members of value types?

2017-05-06 Thread Kelvin Ma via swift-users
If I have a “large” struct like

struct Vertex
{
let x:Double, y:Double
var r:Int, g:Int, b:Int
let s:Double, t:Double
var selected:Bool
}

and I want to pass it to a function without modifying it like

func taxicab_distance(_ v1:Vertex, _ v2:Vertex) -> Double
{
return v2.x - v1.x + v2.y - v1.y
}

Will the entire struct Vertex get copied and pushed onto the stack, or will
only the relevant members be passed to the function?

In other words, does the compiler know to optimize this call down to

func taxicab_distance(v2x:Double, v1x:Double, v2y:Double, v1y:Double) ->
Double
{
return v2x - v1x + v2y - v1y
}

?
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Why does String.CharacterView have reserveCapacity(:)?

2017-05-06 Thread Kelvin Ma via swift-users
Okay I understand most of that, but I still feel it’s misleading to put
`reserveCapacity()` on `CharacterView` and `UnicodeScalarView`.
`reserveCapacity()` should live in a type where its meaning matches up with
the meaning of the `.count` property, ideally the `UTF8View`. Otherwise it
should at least be removed from `CharacterView` and `UnicodeScalarView` and
only live in the parent `String` type.

On Thu, May 4, 2017 at 6:33 AM, Brent Royal-Gordon 
wrote:

> On May 2, 2017, at 12:35 PM, Kelvin Ma via swift-users <
> swift-users@swift.org> wrote:
>
> I’m wondering why the String.CharacterView structure has a
> reserveCapacity(:) member?
>
>
> Because it conforms to the RangeReplaceableCollection protocol, which
> requires `reserveCapacity(_:)`.
>
> More broadly, because you can append characters to the collection, and so
> you might want to pre-size it to reduce the amount of reallocating you
> might need to do in the future.
>
> And even more strangely, why String itself has the same method?
>
>
> Because it has duplicates of those `CharacterView` methods which don't
> address individual characters. (In Swift 4, it will be merged with
> CharacterView.)
>
> It’s even weirder that String.UnicodeScalarView has this method, but it
> reserves `n` `UInt8`s of storage, instead of `n` `UInt32`s of storage.
>
>
> Because the views are simply different wrappers around a single underlying
> buffer type, which stores the string in 8-bit (if all characters are ASCII)
> or 16-bit (if some are non-ASCII). That means that `UnicodeScalarView`
> isn't backed by a UTF-32 buffer; it's backed by an ASCII or UTF-16 buffer,
> but it only generates and accepts indices corresponding to whole
> characters, not the second half of a surrogate pair.
>
> Why not allocate a larger buffer anyway? Most strings use no extraplanar
> characters, and many strings use only ASCII characters. (Even when the user
> works in a non-ASCII language, strings representing code, file system
> paths, URLs, identifiers, localization keys, etc. are usually ASCII-only.)
> By reserving only `n` `UInt8`s, Swift avoids wasting memory, at the cost of
> sometimes having to reallocate and copy the buffer when a string contains
> relatively rare characters. I believe Swift doubles the buffer size on each
> allocation, so we're talking no more than one reallocation for a non-ASCII
> string and two for an extraplanar string. That's quite acceptable.
>
> Also why String.UTF8View and String.UTF16View do not have this method,
> when it would make more sense for them to have it than for String itself
> and String.CharacterView to have it.
>
>
> Because UTF8View and UTF16View are immutable. They don't conform to
> RangeReplaceableCollection and cannot be used to modify the string (since
> you could modify them to generate an invalid string).
>
> --
> Brent Royal-Gordon
> Architechies
>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


[swift-users] Swift build-script Smaller Memory Footprint?

2017-05-06 Thread Brandon B via swift-users
Hello,

I’m installing Swift 3 on FreeBSD 11. After installing the necessary 
dependencies, I now only need to run the build-script.

The problem is that I cannot proceed beyond:

>  Linking CXX executable bin/llvm-lto

because I consistently run out of memory on my 16GB server.

>From what I’ve gathered, the problem lies in  ld  which is apparently infamous 
>for this sort of behavior.

I know that I can run ld without debug options (which would reduce its memory 
footprint dramatically) but I don’t know how I would do that, given that it is 
called by the build-script.

What do I need to do to make the build-script use less memory?

— Brandon Bradley___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users