Swift: Compile Time versus Run Time

Swift: Compile Time versus Run Time

A6a3f76eac79606d705426bcc267dc01?s=128

airspeedswift

May 22, 2015
Tweet

Transcript

  1. 9.

    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. 13.
  3. 18.

    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))
  4. 20.

    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 } } }
  5. 23.

    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) } } } }
  6. 25.

    Using&String extension FourCharCode { init(fromFourCharString str: String) { precondition(str.byteSize ==

    4) self = reduce(str.utf8, 0) { code, byte in (code << 8) | UInt32(byte) } } }
  7. 28.

    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 }
  8. 29.

    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; }
  9. 30.

    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.
  10. 31.

    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
  11. 33.

    Zero%cost)Abstrac-ons struct Int { var value: Builtin.Int64 } func +(lhs:

    Int, rhs: Int) -> Int { precondition(no overflow) }
  12. 37.

    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%!
  13. 38.

    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 } }