差分計算アルゴリズムを用いた高速なUITableView描画

06e251dd7c57b30b6771050dbe88683b?s=47 fumito-ito
August 31, 2018

 差分計算アルゴリズムを用いた高速なUITableView描画

UITableViewをいかに高速に描画、更新するかはiOSアプリケーションの実装において頻繁に遭遇する問題です。

本セッションでは単純な reloadData を用いた場合と差分計算アルゴリズムを用いた場合で実際にどの程度の差が生じるのか検証した結果を提示します。
また、複数の差分計算アルゴリズムとその実装を比較することで、それぞれの実装が適しているケースを提示します。

06e251dd7c57b30b6771050dbe88683b?s=128

fumito-ito

August 31, 2018
Tweet

Transcript

  1. 1 ࠩ෼ܭࢉΞϧΰϦζϜΛ༻͍ ͨߴ଎ͳ UITableView ඳը

  2. 2 ύϑΥʔϚϯε ؾʹͯ͠·͔͢ʁ

  3. 3 “Most apps target a frame rate of 60 FPS,

    Equivalent to 16.67 ms per frame.” https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/ MTLBestPracticesGuide/FrameRate.html
  4. 4 16 ms…

  5. 5 UITableView͕େྔʹฒͿ

  6. 6 UITableViewΛ ଎͍ͨ͘͠

  7. 7 UITableViewΛ଎͘͢Δʹ͸ • CellͷϨϯμϦϯά࠷దԽ • ඇಉظͳσʔλϑΣονͱΩϟογϡ • ඇಉظͳը૾ϩʔυͱΩϟογϡ • ΦϑϨϯμϦϯάΛආ͚Δ

    • αΠζͷࣄલܭࢉͱΩϟογϡ
  8. 8 ඳը͢Δߦ͕গͳ͚Ε ͹଎͍ͷͰ͸…

  9. 9 performBatchUpdates

  10. 10 ࠩ෼ߋ৽Λߦ͏ͨΊʹ͸ • มߋલͷσʔλΛมߋޙͷσʔλʹม׵͢ΔͨΊͷ
 ฤूૢ࡞Λܭࢉ͠ͳͯ͘͸ͳΒͳ͍ • มߋલޙͷσʔλͷ௕͞ΛͦΕͧΕM, Nͱͨ͠৔߹
 ૯౰ͨΓͰܭࢉྔ͸O(M *

    N)ʹͳΔ • ฤूૢ࡞Λܭࢉ͢Δํ๏͸͢Ͱʹଟ͘ͷΞϧΰϦζϜ͕
 ߟҊ͞Ε͓ͯΓɺ͜ΕΒΛ༻͍Δ͜ͱͰܭࢉྔΛখ͘͞
 ͢Δ͜ͱ͕Ͱ͖Δ
  11. 11 ͬ͘͟Γฤूૢ࡞ܭࢉ ΞϧΰϦζϜ

  12. X ͬ͘͟Γฤूڑ཭ΞϧΰϦζϜ • จࣈྻͷฤूૢ࡞Λάϥϑʹϓ ϩοτ͠ɺ࠷খૢ࡞ύεʢฤू ڑ཭ʣΛ୳͢ • ૯ίετΛԾఆͯ͠࠷খίετ Λ୳ࡧ͢Δํ๏ʢMyerʣ •

    ࡟আૢ࡞ͷ૯਺ΛԾఆͯ͠࠷খ ίετΛ୳ࡧ͢Δํ๏ʢWuʣ https://susisu.hatenablog.com/entry/2017/10/09/134032
  13. X ͬ͘͟ΓHeckel๏ • ྆ํͷཁૉྻʹݱΕΔڞ௨͔ͭ
 ̍౓͔͠ग़ݱ͠ͳ͍ཁૉΛ୳͢ • நग़ͨ͠ߦΛى఺ʹڞ௨ϒϩοΫ Λ୳ͯࠩ͠෼͔ΒऔΓআ͘ Paul Heckel

    (Apr 1978), “A technique for isolating differences between files”
  14. 12 ֤ΞϧΰϦζϜͷܭࢉྔ • Myer๏ • ܭࢉྔɿO(N + D^2) ~ O(N

    * D) • D͸ฤूڑ཭ʢฤूૢ࡞ͷ਺ʣ • Wu๏ • ܭࢉྔɿO(N + P * D) ~ O(N * P) • P͸࡟আૢ࡞ͷ਺ɺD͸ฤूڑ཭ • Heckel๏ • ܭࢉྔɿO(N)
  15. 13 ฤूૢ࡞ܭࢉΞϧΰϦζϜͷ࣮૷ • Dwifft • EditDistance • RxDataSources • DifferenceKit

  16. 14 Dwifft • https://github.com/jflinter/Dwifft • Myer๏ͬΆ͍࣮૷ => O(N * D)

    • ࠓճऔΓ্͛ͨ΋ͷͷதͰ͸ʢཧ࿦తʹ͸ʣҰ൪஗͍
  17. 15 EditDistance • https://github.com/kazuhiro4949/EditDistance • Wu๏ͬΆ͍࣮૷ => O(N * P)

    • WuͷΞϧΰϦζϜΛ࣮૷͍ͯ͠Δ΋ͷ͸ҙ֎ͱগͳ͍
  18. 16 RxDataSources • https://github.com/RxSwiftCommunity/RxDataSources • Heckel๏ + α => O(N)

    • IGListKit΋ಉ༷ʹHeckel๏Λ࠾༻͍ͯ͠Δ͕ɺ
 ΑΓ࠷దԽ͞Ε͍ͯΔRxDataSourceΛ࠾༻͢Δ • ࠩ෼ܭࢉΞϧΰϦζϜ෦෼͸ Differentiator.framework
 ͱͯ͠෼཭͞Ε͍ͯΔͷͰଞͷϑϨʔϜϫʔΫ͔Β
 ར༻͢Δ͜ͱ͕ՄೳͰ͋Δ
  19. 17

  20. 18 DifferenceKit • https://github.com/ra1028/DifferenceKit • Heckel๏ + α => O(N)

    • iOSDC1ϲ݄લʹಥ೗ͱͯ͠ݱΕͨ৽੕
  21. 19

  22. 20 ύϑΥʔϚϯεൺֱ

  23. 21 ϨΪϡϨʔγϣϯ • Insert 10% + Delete 10% • ཁૉ਺:

    1,000 • ཁૉ਺: 10,000 • Insert 30% + Delete 30% • ཁૉ਺: 1,000 • ཁૉ਺: 10,000
  24. 22 ύϑΥʔϚϯεൺֱ(1,000ߦ)

  25. 23 ύϑΥʔϚϯεൺֱ(10,000ߦ)

  26. 24 ࠩ෼ߋ৽ύϑΥʔϚϯε(1,000ߦ)

  27. 25 ࠩ෼ߋ৽ύϑΥʔϚϯε(100ߦ)

  28. 26 ಈ͔ͤΔαϯϓϧ • https://github.com/fumito-ito/iOSDC-2018-Sample

  29. 27 ύϑΥʔϚϯεҎ֎ͷൺֱ؍఺ • ଟ࣍ݩ഑ྻʹରԠ͍ͯ͠Δ͔ • ≒ ηΫγϣϯͷαϙʔτ • ॏෳͨ͠σʔλΛڐ༰͢Δ͔ •

    UITableViewͰදݱՄೳͳૢ࡞Λαϙʔτ͍ͯ͠Δ͔
  30. 28 ϥΠϒϥϦͷػೳൺֱ

  31. 29 ೔ܦిࢠ൛ͷࠩ෼ܭࢉ • RxASDataSourceΛ࠾༻ͨ͠ • RxDataSourcesͷޓ׵ϥΠϒϥϦ • ΋ͱ΋ͱར༻͍ͯͨ͠RxSwiftɺTextureͱ૬ੑͷ͍͍
 ϥΠϒϥϦΛ࢖͍͔ͨͬͨ

  32. 30 ೔ܦిࢠ൛Ͱͷվળྫ reloadData ࠩ෼ߋ৽

  33. 31 ࠩ෼ߋ৽ ຊ౰ʹ΍Δ΂͖ʁ

  34. 32 ࠩ෼ߋ৽͸ίετʹݟ߹ͬͯΔʁ • ཁૉ਺ʹൺྫͯ͠ܭࢉίετ͕૿େ͢Δ͸ͣ • ࣮ࡍʹηϧͷ਺͕େ͖͗͢Δ৔߹͸ඇৗʹ஗͘ͳΔ
 ໰୊͕ࢦఠ͞Ε͍ͯΔ • “I have

    a huge data set and - performBatchUpdatesAnimated: completion: is super slow. What do I do?”
 - IGListKit, performBatchUpdates long perform on main thread #803
 https://github.com/Instagram/IGListKit/issues/ 803#issuecomment-305276659
  35. 33 ؾʹͳΔํ͸ͪ͜Β • ʮ5000ߦͷUITableViewΛࠩ෼ߋ৽͢Δʯ • 2018/09/01 14:20 ~ @Track A

    • https://fortee.jp/iosdc-japan-2018/proposal/ 530b6839-cc50-452c-9682-897afa9db18c
  36. 34 ·ͱΊ • ࠩ෼ߋ৽Λ༻͍Δ͜ͱͰUITableViewΛߴ଎ʹ
 ඳը͢Δ͜ͱ͕Ͱ͖Δ • ࠩ෼ͷܭࢉʹΞϧΰϦζϜΛద༻͢Δ͜ͱͰܭࢉྔΛ
 ݮΒ͠ɺύϑΥʔϚϯεΛ޲্ͤ͞Δ͜ͱ͕Ͱ͖Δ • දࣔ͢Δσʔλͷྔ͕େ͖͍৔߹͸ࠩ෼ܭࢉΛ͢Δͷ͔ɺ

    reloadDataΛ͢Δͷ͔ߟ͑ͨํ͕ྑ͍
  37. 35 RxASDataSourceͷ ίϯτϦϏϡʔλʔ ืूதͰ͢ɻ @fumito_ito fumito-ito

  38. 36 ग़య • Paul Heckel (Apr 1978), “A technique for

    isolating differences between files” • James W. Hunt, M. Douglas Mcllory (Jun 1976), “An Algorithm for Differential File Comparison” • E. Myers (1986), “An O(ND) Difference Algorithm and Its Variations”