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

累積和で配列の処理効率を改善しよう

tokizo
June 22, 2022
380

 累積和で配列の処理効率を改善しよう

tokizo

June 22, 2022
Tweet

Transcript

  1. 2022.06.22

    potatotips #78

    tokizo / @tokizuoh
    累積和で処理効率を改善しよう
    配列の

    View full-size slide

  2. コードはSwiftPM経由で利用可能!
    https://github.com/tokizuoh/swift-prefix-sum

    View full-size slide

  3. tokizo / @tokizuoh
    ・ トキゾー

    ・ 株式会社はてな

    ・ HealthKitはイイゾー!

     ・ https://github.com/tokizuoh/contrail

    View full-size slide

  4. こんなときどうしますか?

    View full-size slide

  5. 問題設定
    ・ ランニングアプリ

    ・ 日ごとの距離を管理

    ・ A日からB日までの合計距離が知りたい
    11 km
    5 km 0 km
    0 km
    7 km 0 km 10 km
    15 km 1 km 4 km 0 km 2 km 1 km 7 km
    11 km
    13 km
    0 km 3 km 0 km 0 km 1 km 4 km
    2 km 6 km 3 km 5 km 4 km 2 km 2 km
    12 km 0 km 2 km 1 km 0 km 2 km 0 km
    https://www.irasutoya.com/2019/12/blog-post_26.html

    View full-size slide

  6. 問題設定
    ・ ランニングアプリ

    ・ 日ごとの距離を管理

    ・ A日からB日までの合計距離が知りたい
    11 km
    5 km 0 km
    0 km
    7 km 0 km 10 km
    15 km 1 km 4 km 0 km 2 km 1 km 7 km
    11 km
    13 km
    0 km 3 km 0 km 0 km 1 km 4 km
    2 km 6 km 3 km 5 km 4 km 2 km 2 km
    12 km 0 km 2 km 1 km 0 km 2 km 0 km
    https://www.irasutoya.com/2019/12/blog-post_26.html

    View full-size slide

  7. 問題設定
    ・ ランニングアプリ

    ・ 日ごとの距離を管理

    ・ A日からB日までの合計距離が知りたい
    11 km
    5 km 0 km
    0 km
    7 km 0 km 10 km
    15 km 1 km 4 km 0 km 2 km 1 km 7 km
    11 km
    13 km
    0 km 3 km 0 km 0 km 1 km 4 km
    2 km 6 km 3 km 5 km 4 km 2 km 2 km
    12 km
    15 km 0 km 2 km 1 km 0 km 2 km 0 km
    https://www.irasutoya.com/2019/12/blog-post_26.html

    View full-size slide

  8. 問題設定
    ・ ランニングアプリ

    ・ 日ごとの距離を管理

    ・ A日からB日までの合計距離が知りたい
    11 km
    5 km 0 km
    0 km
    7 km 0 km 10 km
    15 km 1 km 4 km 0 km 2 km 1 km 7 km
    11 km
    13 km
    0 km 3 km 0 km 0 km 1 km 4 km
    2 km 6 km 3 km 5 km 4 km 2 km 2 km
    12 km
    15 km
    = 12 + 0 + 2 + 1
    0 km 2 km 1 km 0 km 2 km 0 km
    https://www.irasutoya.com/2019/12/blog-post_26.html

    View full-size slide

  9. 問題設定
    ・ ランニングアプリ

    ・ 日ごとの距離を管理

    ・ A日からB日までの合計距離が知りたい
    11 km
    5 km 0 km
    0 km
    7 km 0 km 10 km
    15 km 1 km 4 km 0 km 2 km 1 km 7 km
    11 km
    13 km
    0 km 3 km 0 km 0 km 1 km 4 km
    2 km 6 km 3 km 5 km 4 km 2 km 2 km
    12 km
    15 km
    = 12 + 0 + 2 + 1
    0 km 2 km 1 km 0 km 2 km 0 km
    https://www.irasutoya.com/2019/12/blog-post_26.html

    View full-size slide

  10. 問題設定
    ・ ランニングアプリ

    ・ 日ごとの距離を管理

    ・ A日からB日までの合計距離が知りたい
    11 km
    5 km 0 km
    0 km
    7 km 0 km 10 km
    15 km 1 km 4 km 0 km 2 km 1 km 7 km
    11 km
    13 km
    0 km 3 km 0 km 0 km 1 km 4 km
    2 km 6 km 3 km 5 km 4 km 2 km 2 km
    12 km
    15 km
    = 12 + 0 + 2 + 1
    0 km 2 km 1 km 0 km 2 km 0 km
    https://www.irasutoya.com/2019/12/blog-post_26.html
    効率化したい!

    View full-size slide

  11. 累積和を使って効率化

    View full-size slide

  12. 累積和とは
    適切な前処理をしておくことで、配列上の区間
    の総和を求めるクエリを爆速で処理できるよう
    になる手法
    累積和を何も考えずに書けるようにする! - Qiita

    https://qiita.com/drken/items/56a6b68edef8fc605821

    View full-size slide

  13. 累積和とは
    適切な前処理をしておくことで、配列上の区間
    の総和を求めるクエリを爆速で処理できるよう
    になる手法
    累積和を何も考えずに書けるようにする! - Qiita

    https://qiita.com/drken/items/56a6b68edef8fc605821

    View full-size slide

  14. ・ 前処理

    ・ クエリ

    ・ 処理
    累積和 3ステップ

    View full-size slide

  15. 累積和 / 前処理
    3
    4
    5
    6
    2
    7
    1

    View full-size slide

  16. 累積和 / 前処理
    3
    4
    5
    6
    2
    7
    1
    0 0 0
    0 0 0 0
    0
    New !

    View full-size slide

  17. 累積和 / 前処理
    3
    4
    5
    6
    2
    7
    1
    1 0 0
    0 0 0 0
    0

    View full-size slide

  18. 累積和 / 前処理
    3
    4
    5
    6
    2
    7
    1
    1 0
    0 0 0 0
    0
    8

    View full-size slide

  19. 累積和 / 前処理
    3
    4
    5
    6
    2
    7
    1
    1 8
    0 10 16 21 25 28

    View full-size slide

  20. 累積和 / クエリ
    3
    5 4
    6
    2
    7
    1
    1 8
    0 10 16 21 25 28
    ↓この区間の総和を求めたい! (= 17)

    View full-size slide

  21. 累積和 / 処理
    3
    5 4
    6
    2
    7
    1
    1 8
    0 10 16 21 25 28
    ↓この区間の総和を求めたい! (= 17)
    25 - 8 = 17

    View full-size slide

  22. Swiftで実装して

    処理速度を比較してみた

    View full-size slide

  23. Swiftで愚直な手法と累積和を比較
    https://github.com/tokizuoh/swift-prefix-sum/blob/develop/Tests/SwiftPrefixSumTests/PrefixSumArrayTests.swift
    ⇒ 愚直な手法と比べて約23倍速い
    (…そもそも0.07秒なので効率化しなくても問題なさそう)
    配列長10000, 100個のクエリの条件でテスト

    View full-size slide