Swift Tuple index using a variable as the index?

前端 未结 5 843
灰色年华
灰色年华 2021-01-21 08:31

Swift Tuple index using a variable as the index? Anyone know if it is possible to use a variable as the index for a Swift tuple index. I wish to select and item from a tuple usi

5条回答
  •  鱼传尺愫
    2021-01-21 09:00

    So, what people here are saying - don't use a tuple if you don't actually need one - is correct. However, there is one caveat.

    In my experience, using a Swift Array with a static size in performance critical code actually slows down your code by quite a bit. Take a look:

    let clz_lookup = [4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
    func clz(x : UInt32) -> Int {
        guard x != 0 else { return 32 }
        var x = x
        var n = 0
    
        if (x & 0xFFFF0000) == 0 { n  = 16; x <<= 16 } else { n = 0 }
        if (x & 0xFF000000) == 0 { n +=  8; x <<=  8 }
        if (x & 0xF0000000) == 0 { n +=  4; x <<=  4 }
    
        return n + clz_lookup[Int(x >> (32 - 4))]
    }
    

    This is a fairly straight forward piece of code that uses a cached lookup table at the end. However, if we profile this using instruments we'll see that the lookup is actually much slower than the if statements it replaces! My guess is the reason for that is probably bounds checking or something similar, plus that there is an additional pointer indirection in the implementation.

    In any case, that's not good, and since the above is a function that is potentially being called a lot we want to optimise it. A simple technique for that is creating a Tuple instead of an Array, and then simply using withUnsafeMutablePointer to get a pointer directly into the Tuple (which is laid out as a contiguous, static array in memory - exactly what we want in this case!):

    var clz_table = (4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0)
    let clz_lookup = withUnsafeMutablePointer(to: &clz_table) { $0.withMemoryRebound(to: Int.self, capacity: 15) { $0 } }
    

    This can be used exactly like a regular C-style array in that you can index into it and even change the values at particular indices, but there is no way to grow this array. This method of indexing should be much faster than the other solutions that are mentioning reflection, but is potentially unsafe if used wrong.

提交回复
热议问题