<h2>Update</h2>

<p><a href="https://github.com/apple/swift/pull/25286" rel="nofollow noreferrer">This</a> implementation of a random number generator in an interval has been merged into the standard library and should perform better than before:</p>

<pre><code>// s = upperBound; r1, r2 = random numbers from generator
func bounded(s: UInt64, r1:UInt64, r2: UInt64) -&gt; UInt64 {
    // r1 would come from invoking generator's next()
    var m = r1.multipliedFullWidth(by: s)
    if m.low &lt; s {
        // let t = (0 &amp;- s) % s // Lemire's original form
        var t = 0 &amp;- s // O'Neill's modulo optimization
        if t &gt;= s {
            t &amp;-= s
            if t &gt;= s {
                t %= s
            }
        }
        while m.low &lt; t {
            // r2 would come from invoking generator's next()
            m = r2.multipliedFullWidth(by: s)
        }
    }
    return m.high
}
</code></pre>

<p>See the answer below for more details.</p>

<h2>Answer</h2>

<p>An answer to your second question :</p>

<blockquote>
  <p>"Are there any faster methods for random number generation in swift?"</p>
</blockquote>

<p>I've <a href="https://stackoverflow.com/questions/55548872/shuffle-struct-by-int/55549494#55549494">previously used</a> the <a href="http://xoshiro.di.unimi.it/" rel="nofollow noreferrer"><strong>Xoshiro</strong></a> Pseudo-Random Number Generator which is pretty fast.</p>

<p>Here the code used for benchmarking :</p>

<ul>
<li><strong>randomGen1</strong></li>
</ul>

<pre><code>import Foundation

public func randomGen1() {
    let n = 1_000_000
    var sum: UInt32 = 0
    let startTime = CFAbsoluteTimeGetCurrent()
    for _ in 0..&lt;n {
        sum = sum &amp;+ arc4random_uniform(10)
    }
    let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
    print(sum, timeElapsed)
}

do {
    randomGen1()
}
</code></pre>

<ul>
<li><strong>randomGen2</strong></li>
</ul>

<pre><code>public func randomGen2() {
    let n = 1_000_000
    var sum: UInt32 = 0
    let startTime = CFAbsoluteTimeGetCurrent()
    for _ in 0..&lt;n {
        sum = sum &amp;+ UInt32.random(in: 0..&lt;10)
    }
    let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
    print(sum, timeElapsed)
}


do {
    randomGen2()
}
</code></pre>

<ul>
<li>Xoshiro random number generator from <a href="https://github.com/mattgallagher/CwlUtils/blob/e4186dae4ba55ffa478264c8477d01a48fd2b459/Sources/CwlUtils/CwlRandom.swift#L80" rel="nofollow noreferrer">this library</a>:</li>
</ul>

<pre><code>struct Xoshiro: RandomNumberGenerator {
    public typealias StateType = (UInt32, UInt32, UInt32, UInt32)

    private var state: StateType

    public init(seed: StateType) {
        self.state = seed
    }

    public mutating func next() -&gt; Int {
        let x = state.1 &amp;* 5
        let result = ((x &amp;&lt;&lt; 7) | (x &amp;&gt;&gt; 25)) &amp;* 9
        let t = state.1 &amp;&lt;&lt; 9
        state.2 ^= state.0
        state.3 ^= state.1
        state.1 ^= state.2
        state.0 ^= state.3
        state.2 ^= t
        state.3 = (state.3 &amp;&lt;&lt; 21) | (state.3 &amp;&gt;&gt; 11)
        return Int(result)
    }
}

var x = Xoshiro(seed: (UInt32.random(in: 0..&lt;10),  //Other upper limits could be used to increase randomness
    UInt32.random(in: 0..&lt;10),
    UInt32.random(in: 0..&lt;10),
    UInt32.random(in: 0..&lt;10)))

public func randomGen3() {
    let n = 1_000_000
    var sum: UInt32 = 0
    let startTime = CFAbsoluteTimeGetCurrent()
    for _ in 0..&lt;n {
        sum = sum &amp;+ UInt32(abs(x.next()) % 10)
    }
    let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
    print(sum, timeElapsed)
}

do {
    randomGen3()
}
</code></pre>

<p>Xoshiro is fast but does not pass all randomness tests. If security is of concern then you could use <a href="https://lemire.me/blog/2019/03/19/the-fastest-conventional-random-number-generator-that-can-pass-big-crush/" rel="nofollow noreferrer">Wyhash</a>.</p>

<p><a href="https://lemire.me/en/" rel="nofollow noreferrer"><strong>Daniel Lemire</strong></a> (the author of <a href="https://arxiv.org/pdf/1805.10941.pdf" rel="nofollow noreferrer">this</a> paper) has kindly just sent me a <a href="https://github.com/lemire/SwiftWyhash" rel="nofollow noreferrer">Swift implementation</a> of Wyhash:</p>

<pre><code>class WyhashGenerator {
    var seed : UInt64

    let multiplier1 : UInt64 = 0xa3b195354a39b70d
    let multiplier2 : UInt64 = 0x1b03738712fad5c9
    let increment : UInt64 = 0x60bee2bee120fc15

    init(userSeed : UInt64) {
        seed = userSeed;
    }

    func random() -&gt; UInt64 {
        seed &amp;+= increment
        let fullmult1 = seed.multipliedFullWidth(by: multiplier1)
        let m1 = fullmult1.high ^ fullmult1.low;
        let fullmult2 = m1.multipliedFullWidth(by: multiplier2)
        let m2 = fullmult2.high ^ fullmult2.low;
        return m2
    }
}
</code></pre>

<p>It can be used like so:</p>

<pre><code>public func randomGen4() {
    let n = 1_000_000
    var sum: UInt64 = 0
    let startTime = CFAbsoluteTimeGetCurrent()
    let gen = WyhashGenerator(userSeed: 0)
    for _ in 0..&lt;n {
        sum = sum &amp;+ gen.random() % 10
    }
    let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
    print(sum, timeElapsed)
}

do {
    randomGen4()
}
</code></pre>

<hr>

<p>And here are the benchmark results, with the code compiled in the terminal with optimizations (<code>-O</code>) :</p>

<pre><code>arc4random_uniform()  : 0.034s
UInt32.random(in:)    : 0.243s
WyHash64              : 0.002s
Xoshiro               : 0.001s
</code></pre>

<hr>

<p><sup>You can find more random number generators <a href="https://github.com/nvzqz/RandomKit" rel="nofollow noreferrer">here</a>.</sup></p>
Why is Int.random() slower than arc4random_uniform()?
<p>I have used Int.random() method and arc4random_uniform() for number generation speed tests.<br>
Both tests were run in macOS console with build configuration set to release.
Below are codes which I have used for testing. </p>

<pre><code>public func randomGen1() {
    let n = 1_000_000
    let startTime = CFAbsoluteTimeGetCurrent()
    for i in 0..&lt;n {
        _ = arc4random_uniform(10)
    }
    let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
    print(timeElapsed)
}
public func randomGen2() {
    let n = 1_000_000
    let startTime = CFAbsoluteTimeGetCurrent()
    for i in 0..&lt;n {
        _ = Int.random(in: 0..&lt;10)
    }
    let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
    print(timeElapsed)
}
</code></pre>

<p>The times I got are <br>
0.029475092887878418 (for arc4random_uniform(10))<br>
0.20298802852630615  (for Int.random(in: 0..&lt;10))</p>

<p>Why is Int.random() so much slower?<br>
Is there a way to optimise it?<br>
Are there any faster methods for random number generation in swift?</p>