[swift-users] Swift and Threads

2016-09-12 Thread Gerriet M. Denkmann via swift-users
This function works flawlessly in Release build:

func markAndTell( talk: Bool, number: Int)
{
let nbrOfThreads = 8
let step = 2
let itemsPerThread = number * step
let bitLimit = nbrOfThreads * itemsPerThread
var bitfield = [Bool](count: bitLimit, repeatedValue: false)

let queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 
);
dispatch_apply( Int(nbrOfThreads), queue,
{ ( idx: size_t) -> Void in

let startIndex = itemsPerThread * Int(idx)
let endIndex = min( startIndex + itemsPerThread, 
bitLimit )
if talk { print("Thread[\(idx)] does \(startIndex) ..< 
\(endIndex)")}

var currIndex = startIndex
while( currIndex < endIndex )
{
bitfield[currIndex] = true  //  this 
might crash
currIndex += step
}
}
)
}

But it does not work in Debug builds.

“does not work” means: for !talk and any number > 0 or: talk and number ≥ 110:

malloc: *** error for object 0x101007808: incorrect checksum for freed object 
- object was probably modified after being freed. *** set a breakpoint in 
malloc_error_break to debug

Or:
fatal error: UnsafeMutablePointer.initializeFrom non-following overlapping range

Or:
just plain wrong data in bitfield.

So: is the code ok and the compiler broken in Debug mode?
Or is the code fundamentally wrong and that it works in Release is just a fluke?
If so: how could it be fixed?

Btw.: no problems with bitfield malloced into some UnsafeMutablePointer.

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


Re: [swift-users] Swift and Threads

2016-09-13 Thread Gerriet M. Denkmann via swift-users

> On 13 Sep 2016, at 14:49, Quinn The Eskimo! via swift-users 
> <swift-users@swift.org> wrote:
> 
> 
> On 13 Sep 2016, at 05:03, Gerriet M. Denkmann via swift-users 
> <swift-users@swift.org> wrote:
> 
>> Or is the code fundamentally wrong …?
> 
> This one.
> 
> You’re accessing a mutable value (`bitfield`) from multiple threads.  Swift 
> does not support that, even in situations like this where you’re sure that 
> the items are preallocated and that the threads are accessing non-overlapping 
> values.
> 
> As to how you fix this, it kinda depends on your final use for the array.  If 
> you’re OK with the results being split into per-thread chunks, you can have 
> each thread work on its own chunk and then pass the results back to the 
> ‘main’ thread when it’s done.  OTOH, if you need your results in one big 
> array, things get tricky.

Stephen J. Butler just suggested a solution (on CocoaDev) which works and is 
fast and uses no additional memory.

Here it is:

let nbrOfThreads = 8
let step = 2
let itemsPerThread = number * step
let bitLimit = nbrOfThreads * itemsPerThread
var bitfield = [Bool](count: bitLimit, repeatedValue: false)

let queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 );

bitfield.withUnsafeMutableBufferPointer { (inout bitfieldBuffer : 
UnsafeMutableBufferPointer) -> () in
dispatch_apply( Int(nbrOfThreads), queue ) { ( idx: size_t) -> Void in
let startIndex = itemsPerThread * Int(idx)
let endIndex = min( startIndex + itemsPerThread, bitLimit )
if talk { print("Thread[\(idx)] does \(startIndex) ..< \(endIndex)") }

var currIndex = startIndex
while( currIndex < endIndex )
{
bitfieldBuffer[currIndex] = true
currIndex += step
}
}
}

I hope that this is really thread-safe (testing it, I have no problems so far).

Kind regards,

Gerriet.

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


Re: [swift-users] Swift 3 likes to tease me

2016-09-23 Thread Gerriet M. Denkmann via swift-users

> On 23 Sep 2016, at 12:09, Marco S Hyman <m...@snafu.org> wrote:
> 
> On Sep 22, 2016, at 9:51 PM, Gerriet M. Denkmann via swift-users 
> <swift-users@swift.org> wrote:
>> 
>> This line (Swift 3):
>>  if a.responds(to: Selector(“viewControllers") )
>> creates this warning: Use '#selector' instead of explicitly constructing a 
>> 'Selector'
>> 
>> Ok. Following this advice I change it to:
>>  if a.responds(to: #selector(“viewControllers”))
> 
> #selector does not take a string.   It takes a method name.  This is required 
> as the name needs to be mangled/demangled in the conversion between obj-c and 
> swift.
> 
> You might need the class name, too, e.g. #selector(MyClass.viewControllers)

This might be difficult. viewControllers is a property used in several classes, 
e.g. UIPageViewController, UISplitViewController, etc.

Xcode has just given me a new suggestion (probably it noticed that I was not 
quite happy with its former hint):
if a.responds(to: #selector(getter: 
UINavigationController.viewControllers))
but I do not want to be restricted to this special class.
My a is AnyObject and should be treated as such.

Kind regards,

Gerriet.


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


[swift-users] Swift 3 likes to tease me

2016-09-22 Thread Gerriet M. Denkmann via swift-users
This line (Swift 3):
if a.responds(to: Selector(“viewControllers") )
creates this warning: Use '#selector' instead of explicitly constructing a 
'Selector'

Ok. Following this advice I change it to:
if a.responds(to: #selector(“viewControllers"))
and now get an error instead: Argument of ‘#selector' does not refer to an 
'@objc' method, property, or initializer

Why do I get punished for following Xcode’s advice?

Gerriet.

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


[swift-users] How to malloc in Swift 3

2016-09-23 Thread Gerriet M. Denkmann via swift-users
This used to work in Swift 2.2:

var bitfield: UnsafeMutablePointer?
bitfield = UnsafeMutablePointer( malloc( 888 ) )

How is this written in Swift 3.0?

Gerriet.

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


Re: [swift-users] How to malloc in Swift 3

2016-09-23 Thread Gerriet M. Denkmann via swift-users

> On 23 Sep 2016, at 17:08, Svein Halvor Halvorsen via swift-users 
> <swift-users@swift.org> wrote:
> 
> var bitfield: UnsafeMutablePointer?
> bitfield = UnsafeMutablePointer.allocate(capacity: 888)
> 

Excellent! 
I see that “- Postcondition: The pointee is allocated, but not initialized.”

What about calloc then? Or use allocate and do a memset afterwards?

Thanks a lot for your help!

Kind regards,

Gerriet.



>> 23. sep. 2016 kl. 10.47 skrev Gerriet M. Denkmann via swift-users 
>> <swift-users@swift.org>:
>> 
>> This used to work in Swift 2.2:
>> 
>> var bitfield: UnsafeMutablePointer?
>> bitfield = UnsafeMutablePointer( malloc( 888 ) )
>> 
>> How is this written in Swift 3.0?
>> 
>> Gerriet.
>> 
>> ___
>> 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 mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] How to malloc in Swift 3

2016-09-23 Thread Gerriet M. Denkmann via swift-users

> On 23 Sep 2016, at 15:47, Gerriet M. Denkmann via swift-users 
> <swift-users@swift.org> wrote:
> 
> This used to work in Swift 2.2:
> 
> var bitfield: UnsafeMutablePointer?
> bitfield = UnsafeMutablePointer( malloc( 888 ) )
> 
> How is this written in Swift 3.0?

To answer my own question:
This works:
var bitfield: UnsafeMutableRawPointer   
bitfield = UnsafeMutableRawPointer( malloc(888))

But then this stops working:
let theByte = self.bitfield[ 5 ] 

Somehow the bitfield must know that it is a field of bytes (not shorts, ints or 
whatever). But how?

Gerriet.

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


Re: [swift-users] CharacterSet vs Set

2016-10-03 Thread Gerriet M. Denkmann via swift-users

> On 3 Oct 2016, at 19:17, Jean-Denis Muys via swift-users 
>  wrote:
> 
> You are right: I don’t know much about asian languages.
> 
> How would you go about counting consonants, vowels (and tone-marks?) in the 
> most general way?

Iterate over unicodeScalars (in the most general case) - Swift characters are 
probably ok for European languages.

For each unicodeScalar a.k.a codepoint you can use the icu function:
int8_t  chrTyp = u_charType (codepoint) 
This returns the general category value for the code point.
This gives you something like U_OTHER_PUNCTUATION, U_MATH_SYMBOL, 
U_OTHER_LETTER etc.
See enum UCharCategory in 


In European languages ignore U_NON_SPACING_MARKs.

There is a compare:options function for NSString (and probably similar for 
Swift String) which might use the options NSCaseInsensitiveSearch and 
NSDiacriticInsensitiveSearch to find equality between ‘E’, ‘e’ and è, é, Ĕ etc.
That is: for each character (or unicodeScalar) compare to a, e, i, o, u with 
these options.

let str = "HaÁÅǺáXeëẽêèâàZ"

for char in str.characters
{
let vowel = isVowel( char )
print("\(char) is \(vowel ? "vowel" : "consonant")")
}

func isVowel( _ char: Character ) -> Bool
{
let s1 = "\(char)"
let s2 = s1 as NSString
let opt: NSString.CompareOptions = [.diacriticInsensitive, 
.caseInsensitive]

//  no idea how do to this with Strings:
if s2.compare("a", options: opt) == .orderedSame {return true}
if s2.compare("e", options: opt) == .orderedSame {return true}
…
return false
}


If you really want to use Thai, then do NOT ignore U_NON_SPACING_MARKs because 
some vowels are classified thusly.
U+0E01 … U+0E2E are consonants, U+0E30 … U+0E39 and U+0E40 … U+0E44 are vowels.
But then: ‘อ’ is sometimes a (silent) consonant (อยาก), sometimes a vowel (บอ), 
sometimes part of a vowel (มือ), sometimes part of a diphthong (เบื่อ).
Similar for ย: normal consonant (ยาก), part of vowel (ไทย) or diphthong (เมีย).
In the latter case only ม is a consonant, the rest is one single diphthong and 
ี is a U_NON_SPACING_MARK which really is a vowel.
Oh, and don't forget the ligatures ฤ, ฤๅ, ฦ, ฦๅ. These are both a consonant and 
a vowel. Same for ำ: not a ligature but a vowel + consonant.


But to talk about german:
What about diphthongs? “neu” has one consonant + one vowel sound (but 2 vowel 
characters).
What if some silly users don’t know how to type umlauts and write “ueber” 
(instead of correctly “über”). This is really one consonant (+diaeresis).
But beware: “aktuell” is definitely not a misspelling of “aktüll” and has two 
vowels.

Gerriet.

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


Re: [swift-users] CharacterSet vs Set

2016-10-03 Thread Gerriet M. Denkmann via swift-users

> On 3 Oct 2016, at 16:28, Jean-Denis Muys via swift-users 
>  wrote:
> 
> ASCII? Probably not. Latin? perhaps, though not obvious. For example French 
> accented letters would probably have to be handled somehow. Greek or 
> Cyrillic? Perhaps. Other scripts? Unlikely, but what do I know.

Don’t be so Europe-centric. Other people have vowels too.
Thai for example. And here are Swift characters completely useless: กี้ is one 
character (for Swift) but it is really one consonant + one vowel + one 
tone-mark.
So you will have to use unicodeScalars.

Have fun!

Gerriet.

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


Re: [swift-users] How to malloc in Swift 3

2016-09-24 Thread Gerriet M. Denkmann via swift-users

> On 23 Sep 2016, at 19:41, Quinn The Eskimo! via swift-users 
> <swift-users@swift.org> wrote:
> 
> 
> On 23 Sep 2016, at 11:29, Gerriet M. Denkmann via swift-users 
> <swift-users@swift.org> wrote:
> 
>> What about calloc then? Or use allocate and do a memset afterwards?
> 
> For trivial data types (like UInt8) this will work, but if you want to follow 
> the rules I recommend reading the following:
> 
> * UnsafeRawPointer Migration
> 
> <https://swift.org/migration-guide/se-0107-migrate.html>
> 
> * SE-0107 “UnsafeRawPointer API”
> 
> <https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md>
> 
> Spoiler: that’ll point you to `initialize(to:count:)` (-:

Thanks for the links.
By the way: I had already tried to use `initialize(to:count:)` before, but I 
used it as a replacement of allocate, which the compiler did not really like.
Since reading these documents I know that I have to use it after allocate, not 
instead of.

In dealloc I had before:
free( bitfield )
which, to my surprise, the compiler did NOT warn about (should there be a 
warning?)
I have since replace this with:
bitfield.deallocate(capacity: numberUsedInAllocate )


>   *   *   *
> 
> Also, why are you manually allocating this rather than using [UInt8]?  The 
> latter is easier, safer, and likely to have similar levels of efficiency.

I just tried this:  [UInt8] turns out to be nearly 10% slower compared to: 
UnsafeMutablePointer.allocate(capacity:).

Probably depends on the use case, whether 10% less performance is worth the 
easier and safer.
I am trying to compare Swift to ObjC classes (which use malloc), so it would 
not be a fair comparison if the Swift class has to use an UInt8 array.


Kind regards,

Gerriet.



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


[swift-users] QualityOfService for concurrentPerform in Swift 3

2016-09-25 Thread Gerriet M. Denkmann via swift-users
In ObjC:

dispatch_queue_t queue = dispatch_get_global_queue( 
DISPATCH_QUEUE_PRIORITY_HIGH, 0 );  
dispatch_apply( nbrThreads, queue, ^void(size_t idx) …

In Swift 3:
DispatchQueue.concurrentPerform( iterations: nbrThreads) …

How can one specify the DISPATCH_QUEUE_PRIORITY or QualityOfService to be used 
by concurrentPerform?

Gerriet.

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


Re: [swift-users] QualityOfService for concurrentPerform in Swift 3

2016-09-25 Thread Gerriet M. Denkmann via swift-users

> On 25 Sep 2016, at 23:08, Saagar Jha <saa...@saagarjha.com> wrote:
> 
> You might be looking for the DispatchQoS.QoSClass enum.
> 
> Saagar Jha

Probably. But how to make concurrentPerform use any of these enums?

Gerriet.



> 
>> On Sep 25, 2016, at 05:19, Gerriet M. Denkmann via swift-users 
>> <swift-users@swift.org> wrote:
>> 
>> In ObjC:
>> 
>> dispatch_queue_t queue = dispatch_get_global_queue( 
>> DISPATCH_QUEUE_PRIORITY_HIGH, 0 );   
>> dispatch_apply( nbrThreads, queue, ^void(size_t idx) …
>> 
>> In Swift 3:
>> DispatchQueue.concurrentPerform( iterations: nbrThreads) …
>> 
>> How can one specify the DISPATCH_QUEUE_PRIORITY or QualityOfService to be 
>> used by concurrentPerform?
>> 
>> Gerriet.
>> 
>> ___
>> 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] Looping with UInt64

2016-10-12 Thread Gerriet M. Denkmann via swift-users
With:
let nbrBytes = 400_000_000
let localArray = UnsafeMutablePointer.allocate(capacity: nbrBytes)
//  touch every page before summing:
for i in 0 ..< nbrBytes / 4096 { localArray[ 4096 * i ] = 1 }

This rather innocent loop:
var count: UInt64 = 0
for index in 0 ..< loopLimit { count += UInt64( localArray[ Int(index) ] ) }

takes 2.4 times as long if preceded by:
let loopLimit = UInt64(nbrBytes)
compared to:
let loopLimit = Int(nbrBytes)   

Why can’t Swift iterate in UInt64  as efficient as with Int?
Any real issue here which I am overlooking or just a compiler bug?

Gerriet.

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


[swift-users] Why are Swift Loops slow?

2016-10-12 Thread Gerriet M. Denkmann via swift-users
uint64_t nbrBytes = 4e8;
uint64_t count = 0;
for( uint64_t byteIndex = 0; byteIndex < nbrBytes; byteIndex++ )
{
count += byteIndex;
if ( ( byteIndex & 0x ) == 0 ) { count += 1.3; }  (AAA) 
};

Takes 260 msec.

Btw.: Without the (AAA) line the whole loop is done in 10 μsec. A really clever 
compiler!
And with “count += 1” instead of “count += 1.3” it takes 410 msec. Very 
strange. 
But this is beside the point here.


Now Swift:
let nbrBytes = 400_000_000
var count = 0
for byteIndex in 0 ..< nbrBytes
{
count += byteIndex
if ( ( byteIndex & 0x ) == 0 ) {count += Int(1.3);}
}

takes 390 msec - about 50 % more.

Release build with default options.

Gerriet.

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


[swift-users] Counting in Threads

2016-10-12 Thread Gerriet M. Denkmann via swift-users

How to translate this to Swift:

__block atomic_uint_fast64_t counter = ATOMIC_VAR_INIT(0);
dispatch_apply( nbrInterations, queue, ^void(size_t idx)
{
uint64_t tCount = 0;
... do some counting ...
atomic_fetch_add_explicit( , tCount, 
memory_order_relaxed );
}
)

Currently I am using:

var counter: UInt64 = 0
let dsema = DispatchSemaphore(value: 1)  
DispatchQueue.concurrentPerform( iterations: nbrInterations )
{ ( idx: size_t) -> Void in

var tCount: UInt64 = 0
... do some counting ...
_ = dsema.wait(timeout: .distantFuture) 
counter += tCount;
dsema.signal()  
}

Is there a better way?

Gerriet.

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


Re: [swift-users] Why are Swift Loops slow?

2016-10-12 Thread Gerriet M. Denkmann via swift-users

> On 12 Oct 2016, at 23:05, Joe Groff via swift-users <swift-users@swift.org> 
> wrote:
> 
>> 
>> On Oct 12, 2016, at 2:25 AM, Gerriet M. Denkmann via swift-users 
>> <swift-users@swift.org> wrote:
>> 
>> uint64_t nbrBytes = 4e8;
>> uint64_t count = 0;
>> for( uint64_t byteIndex = 0; byteIndex < nbrBytes; byteIndex++ )
>> {
>>  count += byteIndex;
>>  if ( ( byteIndex & 0x ) == 0 ) { count += 1.3; }  (AAA) 
>> };
>> 
>> Takes 260 msec.
>> 
>> Btw.: Without the (AAA) line the whole loop is done in 10 μsec. A really 
>> clever compiler!
>> And with “count += 1” instead of “count += 1.3” it takes 410 msec. Very 
>> strange. 
>> But this is beside the point here.
>> 
>> 
>> Now Swift:
>> let nbrBytes = 400_000_000
>> var count = 0
>> for byteIndex in 0 ..< nbrBytes
>> {
>>  count += byteIndex
>>  if ( ( byteIndex & 0x ) == 0 ) {count += Int(1.3);}
>> }
>> 
>> takes 390 msec - about 50 % more.
>> 
>> Release build with default options.
> 
> This is a useless benchmark because the loop does no observable work in 
> either language.

I quite agree that this is useless as a benchmark.
It is an abstraction of some real code, which has the common feature that 
inside the loop is not done anything lengthy.

Following some very helpful remarks from Greg Parker I was able to improve the 
Swift code by a factor of 3, making it on par with ObjC:
1. using a signed loop counter (factor of 2)
2. using “count = count &+ something” instead of “count += something” (factor 
of 1.5).

So this exercise gave me some very valuable insights into using Swift (or into 
some shortcomings of the current Swift compiler).

Thanks again to Greg Parker for his comments and suggestions!

Kind regards,

Gerriet.

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


Re: [swift-users] How to write better Swift

2017-07-10 Thread Gerriet M. Denkmann via swift-users

> On 10 Jul 2017, at 22:35, Geordie J via swift-users <swift-users@swift.org> 
> wrote:
> 
> Would “didSet" on a normal variable work for you?

willSet/didSet usually is a good solution (which I had forgotten about).

But in my case it seems not to help - see the corrected code below

> var status: Int {
>  didSet { doSomething() }
> }
> 
> Geordie
> 
> 
>> Am 10.07.2017 um 17:34 schrieb Gerriet M. Denkmann via swift-users 
>> <swift-users@swift.org>:
>> 
>> This works (Xcode Version 8.3.2 (8E2002)):
>> 
>> class SomeClass
>> {
>>  private var privateStatus: Int  
>> 
>>  var status: Int
>>  {
>>  get{ return privateStatus }
>>  set(new)
>>  {
>>  if new == privateStatus {return}

oldDerived = derivedStatus // depends on status
privateStatus = new
newDerived = derivedStatus 

if newDerived != oldDerived … do something … 

… do something more here …
>>  }
>>  }
>> }
>> 
>> But is this “privateStatus” really necessary?
>> If not, how can it be avoided?


Quincey had an excellent idea: one should be able to write:

var status: Int
{
var privateStatus: Int  //  makes it much clearer that 
privateStatus really only belongs to status

get{ return privateStatus }
set(new)
{
…
privateStatus = new
}
}

Gerriet.

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


[swift-users] How to write better Swift

2017-07-10 Thread Gerriet M. Denkmann via swift-users
This works (Xcode Version 8.3.2 (8E2002)):

class SomeClass
{
private var privateStatus: Int  

var status: Int
{
get{ return privateStatus }
set(new)
{
if new == privateStatus {return}

… do something here …

privateStatus = new
}
}
}

But is this “privateStatus” really necessary?
If not, how can it be avoided?

Gerriet.

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