Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Swift: Compile Time versus Run Time

Swift: Compile Time versus Run Time

airspeedswift

May 22, 2015
Tweet

Other Decks in Programming

Transcript

  1. Is#this#code#“Swi.”? @objc class C { func doThing() { println("something") }

    } @objc class D { func doThing() { println("something else") } } func takeThing(o: AnyObject) { o.doThing() } takeThing(C()) takeThing(D())
  2. Credit'to'@UINT_MIN'for'the'FourCharacterCode'example,' which'is'a'much'more'useful'case'than'example'I'had'originally,' which'was'10'applicaAons'of'the'XorshiC'generator,'which'also' constantDfolds'at'compile'Ame: struct Seed { let x, y,

    z, w: UInt32 } func xrand(seed: Seed) -> Seed { let t = seed.x ^ (seed.x << 11) return Seed(x: seed.y, y: seed.z, z: seed.w, w: seed.w ^ (seed.w >> 19) ^ (t ^ (t >> 8))) } var r = Seed(x: 2014, y: 12, z: 29, w: 2015) let x = reduce(0..<10, r) { r, _ in xrand(r) } println(String(x.w, radix: 16))
  3. Four%character+Codes extension FourCharCode { init(fromFourCharString str: StaticString) { precondition(str.byteSize ==

    4) self = str.withUTF8Buffer { buf in var result: FourCharCode = 0 for byte in buf { result <<= 8 result |= FourCharCode(byte) } return result } } }
  4. Using&reduce extension FourCharCode { init(fromFourCharString str: StaticString) { precondition(str.byteSize ==

    4) self = str.withUTF8Buffer { buf in reduce(buf, 0) { code, byte in (code << 8) | FourCharCode(byte) } } } }
  5. Using&String extension FourCharCode { init(fromFourCharString str: String) { precondition(str.byteSize ==

    4) self = reduce(str.utf8, 0) { code, byte in (code << 8) | UInt32(byte) } } }
  6. func read_nibble(w: UInt64, i: UInt64) -> UInt64 { let res

    = w >> (i * 4) return res & 0xf } func write_nibble(inout w: UInt64, i: UInt64, v: UInt64) { var mask: UInt64 = 0xf mask <<= (i * 4); w &= ~mask var prom = v; prom <<= (i * 4) w |= prom }
  7. func nibble_sort_word(var arg: UInt64) -> UInt64 { for var i:

    UInt64 = 0; i < 16; ++i { var min = i; for var j = i+1; j < 16; ++j { if read_nibble(arg, j) < read_nibble(arg, min) { min = j } } if (min != i) { var tmp = read_nibble(arg, i) write_nibble(&arg, i, read_nibble(arg, min)) write_nibble(&arg, min, tmp) } } return arg; }
  8. struct Nibbles: MutableCollectionType { var val: UInt64 var startIndex: UInt64

    { return 0 } var endIndex: UInt64 { return 16 } subscript(idx: UInt64) -> UInt64 { get { return (val >> (idx*4)) & 0xf } set(n) { let mask = 0xf << (idx * 4) val &= ~mask val |= n << (idx * 4) } } } // + generator impl.
  9. Now$use$the$standard$library’s$sort var col = Nibbles(val: 0xbadbeef) sort(&col) col.val // is

    0xfeedbba000000000 sizeof(UInt64) == sizeof(Nibbles) write/read/sort!version:!400µs sort(Nibbles)!version:!270µs
  10. Zero%cost)Abstrac-ons struct Int { var value: Builtin.Int64 } func +(lhs:

    Int, rhs: Int) -> Int { precondition(no overflow) }
  11. You$can$write$your$own$fast$generic$func1ons! func insertionsort <C: MutableCollectionType where C.Index: RandomAccessIndexType, C.Generator.Element: Comparable>

    (inout source: C) { for i in indices(source) { for var j=i; j!=source.startIndex && source[j]<source[j-1]; j-- { swap(&source[j-1], &source[j]) } } } This%version:%420µs%!
  12. Don’t&uninten*onally&rewrite&std&lib&func*ons! func insertionsort<C: MutableCollectionType where C.Index: RandomAccessIndexType, C.Generator.Element: Comparable> (inout

    source: C) { if isEmpty(source) { return } for i in source.startIndex.successor()..<source.endIndex { let x = source[i] var j = i while j != source.startIndex { let k = j.predecessor() let cmp = source[k] if x < cmp { source[j] = cmp j = k } else { break } } source[j] = x } }