Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Unsafe Swift

Ray Fix
March 02, 2017

Unsafe Swift

Case study of using unsafe to implement hashable type. Presented at try! Swift 2017 Tokyo, Japan.

Ray Fix

March 02, 2017
Tweet

More Decks by Ray Fix

Other Decks in Programming

Transcript

  1. THE SAFETY OF UNSAFE
    SWIFT
    @RAYFIX

    try! Swift Japan 2017
    1

    View full-size slide

  2. UB
    UNDEFINED BEHAVIOR
    2

    View full-size slide

  3. UNDEFINED
    SCHEDULE
    =
    3

    View full-size slide

  4. SWIFT SAFETY
    4

    View full-size slide

  5. WORKING WITH C
    PERFORMANCE
    LOW LEVEL
    5

    View full-size slide

  6. SWIFT POINTERS
    UnsafeMutableRawBufferPointer
    Mutable
    Raw
    Buffer


    6

    View full-size slide

  7. O(1)
    CONSTANT TIME LOOKUP
    DICTIONARIES AND SETS8

    View full-size slide

  8. O(N)
    LINEAR TIME LOOKUP
    BAD HASH
    O(1) 9

    View full-size slide

  9. struct Angle: Hashable {
    var radians: Double

    var hashValue: Int {
    return radians.hashValue
    }
    }

    ANGLE 10

    View full-size slide

  10. struct Point: Hashable {
    var x, y: Double
    var hashValue: Int {
    return x.hashValue ^ y.hashValue
    }
    }

    ^ COMPOSITION 11

    View full-size slide


  11. struct Point: Hashable {
    var x, y: Double
    var hashValue: Int {
    return "\(x),\(y)".hashValue
    }
    }
    FAKE IT
    Heap Allocations are Expensive!
    12

    View full-size slide

  12. protocol HashAlgorithm {
    init() // 1
    mutating func consume(bytes:) // 2
    var finalValue: Int // 3
    }
    ROBUST COMPOSITION13

    View full-size slide

  13. struct FVN1AHash: HashAlgorithm {
    private var hash: UInt64 = 0xcbf29ce484222325
    private let prime: UInt64 = 0x100000001b3
    mutating func consume(bytes: S)
    where S.Iterator.Element == UInt8 {
    for byte in bytes {
    hash = (hash ^ UInt64(byte)) &* prime
    }
    }
    var finalValue: Int {
    return Int(truncatingBitPattern: hash)
    }
    }
    HASH ALGO AUTHORS14

    View full-size slide

  14. var hashValue: Int {
    var hash = FVN1AHash()
    hash.consume(x)
    hash.consume(y)
    return hash.finalValue
    }
    SAFE EASY CLIENT CODE15

    View full-size slide

  15. UNSAFE CODE SAFELY HIDDEN
    AWAY
    extension HashAlgorithm {
    mutating func consume(_ value: I) {
    var temp = value
    withUnsafeBytes(of: &temp) { rawBufferPointer in
    consume(bytes: rawBufferPointer)
    }
    }
    }

    16

    View full-size slide

  16. Safe, Swifty API for Users
    Safe Customization Points for Library Developers
    Well Tested Unsafe Code
    UNSAFE CODE SAFELY HIDDEN
    AWAY
    17

    View full-size slide