Faster Sieve of Eratosthenes
It takes advantages of the fact that all primes from 5 and above can be written as 6X-1 or 6X+1,


I don't think it does, really. It structures the code around that fact, but to take advantage of it, at a minimum you should replace


    while p &lt;= twoOrThree {
        primes.append(p)
        var q = p * p
        let step = p * (p - 1)
        while q &lt;= n {
            composites[q] = true
            q += step
        }
        p += 1
    }



with

    while p &lt;= twoOrThree {
        primes.append(p)
        p += 1
    }


which in my testing gives a significant speedup.



To maximise the advantage, you could reduce composites to only store flags for \$6X \pm 1\$. Proof of concept code (could be tidier):

    var pidx = 1
    p = 5
    while p &lt;= squareRootN {
        if !composites[pidx] {
            primes.append(p)

            var qidx = 3 * pidx * (pidx + 2) + 1 + (pidx &amp; 1)
            let delta = p &lt;&lt; 1
            let off = (4 - 2 * (pidx &amp; 1)) * pidx + 1
            while qidx &lt; composites.count {
                composites[qidx - off] = true
                composites[qidx] = true
                qidx += delta
            }
            if qidx - off &lt; composites.count {
                composites[qidx - off] = true
            }
        }

        pidx += 1
        p += 2 + 2 * (pidx &amp; 1)
    }

    while p &lt;= n {
        if !composites[pidx] { primes.append(p) }
        pidx += 1
        p += 2 + 2 * (pidx &amp; 1)
    }


This gives a moderate speedup in my testing.