Skip to content

Commit fed1b28

Browse files
committed
Asynchronous calculations to free main thread
1 parent 2dfcf10 commit fed1b28

File tree

4 files changed

+113
-98
lines changed

4 files changed

+113
-98
lines changed

Prime Numbers/PrimeGenerator.swift

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,64 +20,71 @@ func ..<T: Strideable>(left: T, right: T.Stride) -> (T, T.Stride) {
2020
}
2121

2222
func ..<T: Strideable>(left: (T, T.Stride), right: T) -> [T] {
23-
return [T](left.0.stride(through: right, by: left.1))
23+
return [T](stride(from: left.0, through: right, by: left.1))
2424
}
2525

2626
class PrimeGenerator {
2727

2828
static let sharedInstance = PrimeGenerator()
29-
30-
func eratosthenesPrimes(max: Int) -> [Int] {
31-
let m = Int(sqrt(ceil(Double(max))))
32-
let set = NSMutableSet(array: 3..2..max)
33-
set.addObject(2)
34-
for i in (2..1..m) {
35-
if (set.containsObject(i)) {
36-
for j in i^^2..i..max {
37-
set.removeObject(j)
29+
private let eraQueue = DispatchQueue(label: "eraQueue")
30+
private let atQueue = DispatchQueue(label: "atQueue")
31+
32+
func eratosthenesPrimes(_ max: Int, completion:([Int]) -> ()){
33+
34+
eraQueue.async {
35+
let m = Int(sqrt(ceil(Double(max))))
36+
let set = NSMutableSet(array: 3..2..max)
37+
set.add(2)
38+
for i in (2..1..m) {
39+
if (set.contains(i)) {
40+
for j in i^^2..i..max {
41+
set.remove(j)
42+
}
3843
}
3944
}
45+
completion(set.sortedArray(using: [SortDescriptor(key: "integerValue", ascending: true)]) as! [Int])
4046
}
41-
return set.sortedArrayUsingDescriptors([NSSortDescriptor(key: "integerValue", ascending: true)]) as! [Int]
4247
}
4348

44-
func atkinsPrimes(max: Int) -> [Int] {
45-
var is_prime = [Bool](count: max + 1, repeatedValue: false)
46-
is_prime[2] = true
47-
is_prime[3] = true
48-
let limit = Int(ceil(sqrt(Double(max))))
49-
for x in 1...limit {
50-
for y in 1...limit {
51-
var num = 4 * x * x + y * y
52-
if (num <= max && (num % 12 == 1 || num % 12 == 5)) {
53-
is_prime[num] = true
54-
}
55-
num = 3 * x * x + y * y
56-
if (num <= max && num % 12 == 7) {
57-
is_prime[num] = true
58-
}
59-
if (x > y) {
60-
num = 3 * x * x - y * y
61-
if (num <= max && num % 12 == 11) {
49+
func atkinsPrimes(_ max: Int, completion:([Int]) -> ()) {
50+
atQueue.async {
51+
var is_prime = [Bool](repeating: false, count: max + 1)
52+
is_prime[2] = true
53+
is_prime[3] = true
54+
let limit = Int(ceil(sqrt(Double(max))))
55+
for x in 1...limit {
56+
for y in 1...limit {
57+
var num = 4 * x * x + y * y
58+
if (num <= max && (num % 12 == 1 || num % 12 == 5)) {
59+
is_prime[num] = true
60+
}
61+
num = 3 * x * x + y * y
62+
if (num <= max && num % 12 == 7) {
6263
is_prime[num] = true
6364
}
65+
if (x > y) {
66+
num = 3 * x * x - y * y
67+
if (num <= max && num % 12 == 11) {
68+
is_prime[num] = true
69+
}
70+
}
6471
}
6572
}
66-
}
67-
if limit > 5 {
68-
for i in 5...limit {
69-
if is_prime[i] {
70-
for j in (i * i)..i..max {
71-
is_prime[j] = false
73+
74+
if limit > 5 {
75+
for i in 5...limit {
76+
if is_prime[i] {
77+
for j in (i * i)..i..max {
78+
is_prime[j] = false
79+
}
7280
}
7381
}
7482
}
83+
var primesArray = [Int]()
84+
for (idx, val) in is_prime.enumerated() {
85+
if val == true { primesArray.append(idx) }
86+
}
87+
completion(primesArray)
7588
}
76-
var primesArray = [Int]()
77-
for (idx, val) in is_prime.enumerate() {
78-
if val == true { primesArray.append(idx) }
79-
}
80-
return primesArray
8189
}
82-
83-
}
90+
}

Prime Numbers/Primes/Primes/Base.lproj/Main.storyboard

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@
2020
<subviews>
2121
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="bQv-Df-Olo">
2222
<subviews>
23-
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" text="Getting primes using the sieve of Eratosthenes" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="4V8-CM-o6m">
23+
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" text="Getting primes using the sieve of Eratosthenes..." textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="4V8-CM-o6m">
2424
<color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="0.69411764710000001" alpha="1" colorSpace="calibratedRGB"/>
2525
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
2626
<fontDescription key="fontDescription" type="system" pointSize="14"/>
2727
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
2828
</textView>
29-
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" text="Getting primes using Atkin's sieve" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="FSt-V7-5y0">
29+
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" text="Getting primes using Atkin's sieve..." textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="FSt-V7-5y0">
3030
<color key="backgroundColor" red="0.25098040700000002" green="0.50196081400000003" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
3131
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
3232
<fontDescription key="fontDescription" type="system" pointSize="14"/>

Prime Numbers/Primes/Primes/PrimeGenerator.swift

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -26,61 +26,65 @@ func ..<T: Strideable>(left: (T, T.Stride), right: T) -> [T] {
2626
class PrimeGenerator {
2727

2828
static let sharedInstance = PrimeGenerator()
29-
30-
31-
32-
29+
private let eraQueue = DispatchQueue(label: "eraQueue")
30+
private let atQueue = DispatchQueue(label: "atQueue")
31+
3332
func eratosthenesPrimes(_ max: Int, completion:([Int]) -> ()){
34-
let m = Int(sqrt(ceil(Double(max))))
35-
let set = NSMutableSet(array: 3..2..max)
36-
set.add(2)
37-
for i in (2..1..m) {
38-
if (set.contains(i)) {
39-
for j in i^^2..i..max {
40-
set.remove(j)
33+
34+
eraQueue.async {
35+
let m = Int(sqrt(ceil(Double(max))))
36+
let set = NSMutableSet(array: 3..2..max)
37+
set.add(2)
38+
for i in (2..1..m) {
39+
if (set.contains(i)) {
40+
for j in i^^2..i..max {
41+
set.remove(j)
42+
}
4143
}
4244
}
45+
completion(set.sortedArray(using: [SortDescriptor(key: "integerValue", ascending: true)]) as! [Int])
4346
}
44-
completion(set.sortedArray(using: [SortDescriptor(key: "integerValue", ascending: true)]) as! [Int])
4547
}
4648

4749
func atkinsPrimes(_ max: Int, completion:([Int]) -> ()) {
48-
var is_prime = [Bool](repeating: false, count: max + 1)
49-
is_prime[2] = true
50-
is_prime[3] = true
51-
let limit = Int(ceil(sqrt(Double(max))))
52-
for x in 1...limit {
53-
for y in 1...limit {
54-
var num = 4 * x * x + y * y
55-
if (num <= max && (num % 12 == 1 || num % 12 == 5)) {
56-
is_prime[num] = true
57-
}
58-
num = 3 * x * x + y * y
59-
if (num <= max && num % 12 == 7) {
60-
is_prime[num] = true
61-
}
62-
if (x > y) {
63-
num = 3 * x * x - y * y
64-
if (num <= max && num % 12 == 11) {
50+
atQueue.async {
51+
var is_prime = [Bool](repeating: false, count: max + 1)
52+
is_prime[2] = true
53+
is_prime[3] = true
54+
let limit = Int(ceil(sqrt(Double(max))))
55+
for x in 1...limit {
56+
for y in 1...limit {
57+
var num = 4 * x * x + y * y
58+
if (num <= max && (num % 12 == 1 || num % 12 == 5)) {
6559
is_prime[num] = true
6660
}
61+
num = 3 * x * x + y * y
62+
if (num <= max && num % 12 == 7) {
63+
is_prime[num] = true
64+
}
65+
if (x > y) {
66+
num = 3 * x * x - y * y
67+
if (num <= max && num % 12 == 11) {
68+
is_prime[num] = true
69+
}
70+
}
6771
}
6872
}
69-
}
70-
if limit > 5 {
71-
for i in 5...limit {
72-
if is_prime[i] {
73-
for j in (i * i)..i..max {
74-
is_prime[j] = false
73+
74+
if limit > 5 {
75+
for i in 5...limit {
76+
if is_prime[i] {
77+
for j in (i * i)..i..max {
78+
is_prime[j] = false
79+
}
7580
}
7681
}
7782
}
83+
var primesArray = [Int]()
84+
for (idx, val) in is_prime.enumerated() {
85+
if val == true { primesArray.append(idx) }
86+
}
87+
completion(primesArray)
7888
}
79-
var primesArray = [Int]()
80-
for (idx, val) in is_prime.enumerated() {
81-
if val == true { primesArray.append(idx) }
82-
}
83-
completion(primesArray)
8489
}
85-
8690
}

Prime Numbers/Primes/Primes/ViewController.swift

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class ViewController: UIViewController {
1515

1616
override func viewDidLoad() {
1717
super.viewDidLoad()
18-
performPrimesGeneration()
18+
self.performPrimesGeneration()
1919
}
2020

2121
override func didReceiveMemoryWarning() {
@@ -25,27 +25,31 @@ class ViewController: UIViewController {
2525

2626
func performPrimesGeneration() {
2727

28-
let primesTo = 1_000
28+
let eraMax = 1_000_000 // max integer for Eratosthenes primes
29+
let atMax = 1_000 // max integer for Atkins prime
2930

3031
let primeGenerator = PrimeGenerator.sharedInstance
3132

32-
var startDate = Date()
33-
var endDate = Date()
33+
let eraStartDate = Date()
3434
var era_sieve = [Int]()
35-
primeGenerator.eratosthenesPrimes(primesTo) { (primesArray) in
35+
primeGenerator.eratosthenesPrimes(eraMax) { (primesArray) in
3636
era_sieve = primesArray
37-
endDate = Date()
38-
print("Found \(era_sieve.count) primes in : \(endDate.timeIntervalSince(startDate) * 1000) ms.")
39-
self.eraSieveTextView.text = era_sieve.description
37+
let eraEndDate = Date()
38+
print("Found \(era_sieve.count) primes in : \(eraEndDate.timeIntervalSince(eraStartDate) * 1000) ms.")
39+
DispatchQueue.main.async(execute: {
40+
self.eraSieveTextView.text = era_sieve.description
41+
})
4042
}
4143

42-
startDate = Date()
44+
let atStartDate = Date()
4345
var at_sieve = [Int]()
44-
primeGenerator.atkinsPrimes(primesTo) { (primesArray) in
46+
primeGenerator.atkinsPrimes(atMax) { (primesArray) in
4547
at_sieve = primesArray
46-
endDate = Date()
47-
print("Found \(at_sieve.count) primes in : \(endDate.timeIntervalSince(startDate) * 1000) ms.")
48-
self.atSieveTextView.text = at_sieve.description
48+
let atEndDate = Date()
49+
print("Found \(at_sieve.count) primes in : \(atEndDate.timeIntervalSince(atStartDate) * 1000) ms.")
50+
DispatchQueue.main.async(execute: {
51+
self.atSieveTextView.text = at_sieve.description
52+
})
4953
}
5054
}
5155
}

0 commit comments

Comments
 (0)