Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Hashable in Swift

Hashable in Swift

Presentation about Swift Hasable protocol

Avatar for Lukasz Pikor

Lukasz Pikor

March 24, 2017
Tweet

More Decks by Lukasz Pikor

Other Decks in Programming

Transcript

  1. Things to remember if a == b then a.hashValue ==

    b.hashValue But reverse is not true!
  2. Things to remember A = false // hash value =

    0 b = true // hash value = 1
  3. Things to remember There is no guarantee that a hash

    value will be the same for different executions of your code - don’t save iT
  4. Things to remember But for given app runtime, hash for

    given object should be always the same hash(obj1) // 111 hash(obj1) // 111 hash(obj1) // 111
  5. conforming to hashable Simple? No performance it’s very important to

    avoid collisions Cryptographic hash function Locality-sensitive hashing Avalanche effect uniformity Caveats with floating-points values
  6. conforming to hashable Simple? No var hashValue: Int { return

    x.hashValue ^ y.hashValue } let (width, height) = (500, 500) let total = width * height var hashes = Set<Int>() for x in 0..<width { for y in 0..<height { hashes.insert(GridPoint(x: x, y: y).hashValue) } } print("\(hashes.count) unique hashes out of a total of \(total).”) // 1024 unique hashes out of a total of 1_000_000 99.9% of values triggers a hash collision.
  7. Better Way No need to reinvent the weel. use sourcery!

    var hashValue: Int { return combineHashes([firstName.hashValue,lastName.hashValue]) }
  8. Better Way No need to reinvent the weel. Or Any

    other already tested method. extension String { var djb2hash: Int { let unicodeScalars = self.unicodeScalars.map { $0.value } return unicodeScalars.reduce(5381) { ($0 << 5) &+ $0 &+ Int($1) } } }
  9. Even Better Way protocol Hasher { mutating func finish() ->

    Int mutating func write(bytes: UnsafeRawBufferPointer) } protocol HashVisitable: Equatable { func hash<H: Hasher>(_ hasher: inout H) }
  10. New code extension GridPoint: HashVisitable { func hash<H: Hasher>(_ hasher:

    inout H) { self.x.hash(&hasher) self.y.hash(&hasher) } }