Swift:有没有比“\(array)”更快的方法来散列Ints数组

时间:2017-08-09 00:22:31

标签: swift string performance

我想实现一个String,其中键的类型为Int

字符串键是通过字面连接[UInt8]数组生成的(它基本上是一个地址)。

即。地址[0,10,32]的哈希值为“01032”。

值永远不会高于255--实际上我可以使用func testPerformance() { let address = [10, 176, 12] //should become "1017612" self.measure { for _ in 0..<10_000 { let key = "\(address[0])\(address[1])\(address[2])" } } }

我在XCode中进行了一些测试并获得了不错的表现。 0.036秒:

{{1}}

我的问题:是否有一个较轻的重量字符串类型或方法可以做到我想要的速度比这更快?根据我的理解,Swift的String类是非常重量级的,下面是各种添加的字符信息:

https://medium.com/@tonyallevato/strings-characters-and-performance-in-swift-a-deep-dive-b7b5bde58d53

2 个答案:

答案 0 :(得分:2)

我不明白你为什么要首先制作字符串的所有开销。你有小Ints,所以为什么不计算一个独特的Int作为关键:

str2double(regexp('bla bal bli : 3 5 12 15.4 -266','(-?\d+\.?\d?)','match'))

这是非常快速和自我散列,原始组件可以很容易地通过规则提取。

或者,您可以使用三个Int属性的自定义结构,您已在其上实现Hashable(通过相同的规则)和Equatable(通过明显的规则)。

答案 1 :(得分:1)

如果您的应用程序对性能敏感,那么您可能希望避免使用数组来修复具有两个或三个成员的数据。数组在堆上分配缓冲区,并且需要对这些缓冲区进行引用计数。这两个事实都具有性能影响。在绝大多数情况下它们可以忽略不计,但是在处理大量数据的紧密循环中(例如网络切换逻辑),你想要避免它们。

尝试这样的事情:

struct TwoByteAddress: Hashable {
    let a: UInt8
    let b: UInt8

    init(_ a: UInt8, _ b: UInt8) {
        self.a = a
        self.b = b
    }

    static func ==(lhs: TwoByteAddress, rhs: TwoByteAddress) -> Bool {
        return lhs.a == rhs.a && lhs.b == rhs.b
    }

    var hashValue: Int {
        return Int(a) << 8 | Int(b)
    }
}

struct ThreeByteAddress: Hashable {
    let twoByteAddress: TwoByteAddress
    let c: UInt8

    init(_ a: UInt8, _ b: UInt8, _ c: UInt8) {
        self.twoByteAddress = TwoByteAddress(a, b)
        self.c = c
    }

    static func ==(lhs: ThreeByteAddress, rhs: ThreeByteAddress) -> Bool {
        return lhs.twoByteAddress == rhs.twoByteAddress && lhs.c == rhs.c
    }

    var hashValue: Int {
        return twoByteAddress.hashValue << 8 | Int(c)
    }
}