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

DifferenceKit in Action

439ebe4787a98881df8a59d41baf4a43?s=47 Ryo Aoyama
January 21, 2020

DifferenceKit in Action

try! Swift Tokyo 2020 Meetup!!
Twitter hashtag: #tryswiftconf_meetup


Ryo Aoyama

January 21, 2020

More Decks by Ryo Aoyama

Other Decks in Programming


  1. DifferenceKit in Action try! Swift Tokyo 2020 Meetup!! Jan 2020

  2. Ryo Aoyama CyberAgent, Inc. CATS productivity team Twitter: @ra1028fe5 GitHub:

    @ra1028 OSS: DifferenceKit, Carbon, swift-mod, etc…
  3. DifferenceKit https://github.com/ra1028/DifferenceKit Ver: 1.1.5 Star: 2.3k Fork: 133 A fast

    and flexible O(n) difference algorithm framework for Swift collection.
  4. Works on many production app LINE Mercari Uber CyberAgent Yahoo

    Japan PayPay dely NIKKEI and more… eureka
  5. Why we use diffing algorithm • For performance • For

    beautiful animation • For declarative programming • For business logic segregation
  6. Ordered N-items List UI

  7. When insert an item to the list, reloadDate() will calculates

    for all items. It’s not efficient Reload
  8. UI calculations are very slow and will force the main

    thread. Reload Slow Slow Slow Slow
  9. Improving list UI performance by updating only the differences. Reload

  10. performBatchUpdates can partially update items with animations let deleteIndexPaths: [IndexPath]

    let insertIndexPaths: [IndexPath] let moveIndexPaths: (from: IndexPath, to: IndexPath) let reloadIndexPaths: [IndexPath] tableView.performBatchUpdates({ tableView.deleteRows(at: deleteIndexPaths, with: .automatic) tableView.insertRows(at: insertIndexPaths, with: .automatic) tableView.moveRow(at: moveIndexPaths.from, to: moveIndexPaths.to) tableView.reloadRows(at: reloadIndexPaths, with: .automatic) })
  11. Now, do you know which item was inserted?

  12. How can I programmatically know how the item array requested

    to the network has changed?
  13. Diffing algorithm Calculates the diffs before and after updating the

    array. https://en.wikipedia.org/wiki/Diff Wiki:
  14. DifferenceKit let source: [Item] let target: [Item] let changeset =

    StagedChangeset(source: source, target: target) tableView.reload(using: changeset, with: .automatic) { data in self.data = data }
  15. Paul Heckel’s Algorithm DifferenceKit uses… Paper: A technique for isolating

    differences between files https://dl.acm.org/doi/10.1145/359460.359467 With O(N) complexity, linear function time can be expected regardless of data size and changes. Ideal for UI calculations, IMO.
  16. Paul Heckel’s Algorithm DifferenceKit uses… Optimizations in terms of +

    • Algorithm • Swift lang
  17. Major Diffing Algorithms Author Myers Wu Heckel complexity O(ND) O(NP)

    O(N) insert ✅ ✅ ✅ delete ✅ ✅ ✅ move ⚠ ⚠ ✅ update ❌ ❌ ✅ shortest? Yes Yes No http://www.xmailserver.org/diff2.pdf http://documents.scribd.com/docs/10ro9oowpo1h81pgh1as.pdf https://publications.mpi-cbg.de/Wu_1990_6334.pdf
  18. Swift Library Comparisons Disclaimer: These DO NOT compete for the

    “Best” of the library.
  19. Library Algorithms

  20. Performance Comparison • 3x slower • 20x slower • 7x

    slower • 18x slower • 4500x slower • 5400x slower • 140x slower From 100,000 elements to 10,000 deleted, 10,000 inserted and 2,000 shuffled BLAZING FAST !
  21. Functionality Comparison Supported Collection

  22. Functionality Comparison Supported Element Diff

  23. Functionality Comparison Supported Section Diff

  24. DifferenceKit in Future

  25. DiffableDataSource https://developer.apple.com/videos/play/wwdc2019/220/ is pretty solid solution for diffing in list

    UI items. But, DifferenceKit is more loosely-coupled, white-boxed and for any usage (mainly UI).
  26. SwiftUI https://developer.apple.com/xcode/swiftui/ New generation, personally, I hope SwiftUI will eliminate

    the DifferenceKit. Currently, SwiftUI.List has no customizability. We should use UITableView and UICollectionView as before. DifferenceKit will be useful for a while.
  27. Thanks Twitter: @ra1028fe5 GitHub: @ra1028 Ryo Aoyama