Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Swift 2 (& lldb) シンポジウム

5,682 views

Published on

2015/08/30 渋谷 dotsで行われたSwift2シンポジウムのスライドです.

Published in: Engineering
  • Be the first to comment

Swift 2 (& lldb) シンポジウム

  1. 1. Yuichi Yoshida Chief engineer, DENSO IT Laboratory, Inc. @sonson_twit © 2014 DENSO IT Laboratory, Inc., All rights reserved. Redistribution or public display not permitted without written permission from DENSO IT Laboratory, Inc. Value type programmingの話もしたい Programming Swift 2 (& LLDB) シンポジウム foldrをとにかく速くする
  2. 2. 自己紹介 2tchの中の人 • iOS好きです • 2tch(2ちゃんねるビューア) • iOS SDK Hacksなど • 研究・開発 • コンピュータビジョン • 機械学習 • 画像検索サービスとか • 車向けサービスやハードウェアとか
  3. 3. 本業
  4. 4. reddift Swift Reddit API Wrapper • 1億人以上のアメリカのSNS • APIあり • Objective-CのAPI Wrapperはあり • OAuth2に対応してない • Swiftじゃない • よし,いっちょ,趣味+勉強がてら作るか! • MIT License https://github.com/sonsongithub/reddift
  5. 5. foldrを速くしたい
  6. 6. Haskellにかぶれ中
  7. 7. foldrとfoldl (畳み込み) • Haskellの高階関数の中にfoldl, foldrというものがある • 良く使われるらしい x + a0 2 + a1 2 + a2 2 foldl foldr x + a2 2 + a1 2 + a0 2
  8. 8. 使い方∼たとえば逆順 — Haskell
 rev :: [a] -> [a] rev = foldl (acc x -> x (: (acc-1)) [] — Swift
 func rev<T>(array:[T]) -> [T] { return array.reduce([]) { (acc:[T], x:T) -> [T] in [x] + acc } }
  9. 9. foldlをSwiftで実装してみよう foldl = reduce 終了
  10. 10. foldrをSwiftで実装してみよう foldr = reverse().reduce 終了・・・・・?
  11. 11. 遅い extension CollectionType { func foldr_reduce<T>(accm:T, f: (T, Self.Generator.Element) -> T) -> T { return self.reverse().reduce(accm) { f($0, $1) } } func foldl_reduce<T>(accm:T, @noescape f: (T, Self.Generator.Element) -> T) -> T { return self.reduce(accm) { f($0, $1) } } }
  12. 12. 理由は? • 高階関数で違いが有る? • 再帰,for, forEach, reduce…. • @noescape • 必要ないのに毎回キャプチャするのが遅い? • 考えにくいけどなぁ • reverseに何か問題がある • そのまま→速い • reverseする→遅い • 怪しい・・・
  13. 13. 実装 - 再帰 // recursive var g = self.generate() func next() -> T { return g.next().map {x in f(x, next())} ?? accm } return next() Haskellは再帰が愛されてるのに・・・・ すぐにスタックを食いつぶすので使えない
  14. 14. 実装 - for // recursive var result = accm for temp in self.reverse() { result = f(temp, result) } return result
  15. 15. 実装 - 新参forEach // forEach var result = accm self.reverse().forEach { (t) -> () in result = f(t, result) } return result
  16. 16. reverseが怪しい • @norio_nomuraさんから色々アドバイス • Swiftのコードを眺めていると,色々判明
  17. 17. 普通のreverseっぽい extension SequenceType { /// Return an `Array` containing the elements of `self` in reverse /// order. /// /// Complexity: O(N), where N is the length of `self`. @warn_unused_result public func reverse() -> [Self.Generator.Element] }
  18. 18. 発見!O(1)とか書いてる extension CollectionType where Index : BidirectionalIndexType { /// Return the elements of `self` in reverse order. /// /// - Complexity: O(1) @warn_unused_result public func reverse() -> ReverseCollection<Self> } extension CollectionType where Index : RandomAccessIndexType { /// Return the elements of `self` in reverse order. /// /// - Complexity: O(1) @warn_unused_result public func reverse() -> ReverseRandomAccessCollection<Self> }
  19. 19. ReverseCollection /// A Collection that presents the elements of its `Base` collection /// in reverse order. /// /// - Note: This type is the result of `x.reverse()` where `x` is a /// collection having bidirectional indices. /// /// The `reverse()` method is always lazy when applied to a collection /// with bidirectional indices, but does not implicitly confer /// laziness on algorithms applied to its result. In other words, for /// ordinary collections `c` having bidirectional indices: /// /// * `c.reverse()` does not create new storage /// * `c.reverse().map(f)` maps eagerly and returns a new array /// * `c.lazy.reverse().map(f)` maps lazily and returns a `LazyMapCollection` /// /// - See also: `ReverseRandomAccessCollection`
  20. 20. ReverseRandomAccessCollection /// A Collection that presents the elements of its `Base` collection /// in reverse order. /// /// - Note: This type is the result of `x.reverse()` where `x` is a /// collection having random access indices. /// - See also: `ReverseCollection`
  21. 21. この型にだけextensionを実装してみる extension CollectionType where Index : RandomAccessIndexType { func foldr_loop2<T>(accm:T, @noescape f: (Self.Generator.Element, T) -> T) -> T { var result = accm for temp in self.reverse() { result = f(temp, result) } return result } func foldr_reduce2<T>(accm:T, @noescape f: (T, Self.Generator.Element) -> T) -> T { return self.reverse().reduce(accm) { f($0, $1) } } func foldr_forEach2<T>(accm:T, @noescape f: (Self.Generator.Element, T) -> T) -> T { var result = accm self.reverse().forEach { (t) -> () in result = f(t, result) } return result } }
  22. 22. 結果(線形)
  23. 23. 結果(対数)
  24. 24. ベンチマークテスト • https://github.com/sonsongithub/testFoldr
  25. 25. value or reference
  26. 26. Value type programmingはどこまで? • ListViewController • ここでコールバックでリストをうけとる • DetailViewController • ListViewCon.からリストの要素ひとつを受け取る • 詳細表示 • 編集
  27. 27. Pros. and cons. • Value type. • 権限と役割が明確 • 速い・・・・? • ポインタに慣れきってるとつらい • コードがわかりやすい?とは思えない. • Reference type. • C型オールドタイプにはわかりやすい • 権限と役割がめちゃくちゃ • たまにデータがめちゃくちゃになる
  28. 28. デンソーアイティーラボラトリでは、          研究者,エンジニアを絶賛募集中です。 興味のある方はこちら。https://www.d-itlab.co.jp/recruit/ 画像処理・機械学習・信号処理・自然言語処理など

×