git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 0/9] reftable: optimize write performance

From
Patrick Steinhardt <ps@pks.im>
Date
Apr 2, 2024, 17:29 UTC
Message-ID
<cover.1712078736.git.ps@pks.im>
Hi,

this is my first patch series taking an actual look at write performance for the reftable backend. This series addresses two major pain points:

  - Duplicate directory/file conflict checks when writing refs.
  - Allocation churn when compressing log blocks.

Overall though I found that there is not much of a point to investigate write performance in the reftable library itself, at least not right now. This is mostly because the write performance is heavily dominated by random ref reads. And while past patch series have optimized scanning through refs linearly, seeking random refs isn't well-optimized yet. So once all in-flight series relating to reftable performance have landed I will focus on random ref reads next.

For the bigger picture, the following benchmarks show perfomance compared to the "files" backend after applying this patch series.

Writing many refs in a single transaction:
  Benchmark 1: update-ref: create many refs (refformat = files, refcount = 100000)
    Time (mean ± σ):     10.085 s ±  0.057 s    [User: 1.876 s, System: 8.161 s]
    Range (min … max):   10.013 s … 10.202 s    10 runs
  Benchmark 2: update-ref: create many refs (refformat = reftable, refcount = 100000)
    Time (mean ± σ):      2.768 s ±  0.018 s    [User: 1.381 s, System: 1.383 s]
    Range (min … max):    2.745 s …  2.804 s    10 runs
  Summary
    update-ref: create many refs (refformat = reftable, refcount = 100000) ran
      3.64 ± 0.03 times faster than update-ref: create many refs (refformat = files, refcount = 100000)
And for writing many refs sequentially in separate transactions:
  Benchmark 1: update-ref: create refs sequentially (refformat = files, refcount = 10000)
    Time (mean ± σ):     40.286 s ±  0.086 s    [User: 22.241 s, System: 17.912 s]
    Range (min … max):   40.166 s … 40.410 s    10 runs
  Benchmark 2: update-ref: create refs sequentially (refformat = reftable, refcount = 10000)
    Time (mean ± σ):     44.046 s ±  0.137 s    [User: 23.790 s, System: 20.146 s]
    Range (min … max):   43.813 s … 44.301 s    10 runs
  Summary
    update-ref: create refs sequentially (refformat = files, refcount = 10000) ran
      1.09 ± 0.00 times faster than update-ref: create refs sequentially (refformat = reftable, refcount = 10000)

This is to the best of my knowledge last area where the "files" backend outperforms the "reftable" backend. This is partially also due to the fact that writes perform auto-compaction with the "reftable" backend.

Patrick
Patrick Steinhardt (9):
  refs/reftable: fix D/F conflict error message on ref copy
  refs/reftable: perform explicit D/F check when writing symrefs
  refs/reftable: skip duplicate name checks
  refs/reftable: don't recompute committer ident
  reftable/writer: refactorings for `writer_add_record()`
  reftable/writer: refactorings for `writer_flush_nonempty_block()`
  reftable/block: reuse zstream when writing log blocks
  reftable/block: reuse compressed array
  reftable/writer: reset `last_key` instead of releasing it
 refs/reftable-backend.c    |  80 ++++++++++++++++++-------
 reftable/block.c           |  83 ++++++++++++++++----------
 reftable/block.h           |   4 ++
 reftable/writer.c          | 119 ++++++++++++++++++++++++-------------
 t/t0610-reftable-basics.sh |  35 ++++++++++-
 5 files changed, 227 insertions(+), 94 deletions(-)
-- 
2.44.GIT
Next: Patrick Steinhardt
Message 1 of 49 in “reftable: optimize write performance”
  1. 0/9 reftable: optimize write performancePatrick Steinhardt, Apr 2, 2024
  2. 1/9 refs/reftable: fix D/F conflict error message on ref copyPatrick Steinhardt, Apr 2, 2024
  3. Junio C HamanoApr 3, 2024
  4. 2/9 refs/reftable: perform explicit D/F check when writing symrefsPatrick Steinhardt, Apr 2, 2024
  5. 3/9 refs/reftable: skip duplicate name checksPatrick Steinhardt, Apr 2, 2024
  6. 4/9 refs/reftable: don't recompute committer identPatrick Steinhardt, Apr 2, 2024
  7. Junio C HamanoApr 3, 2024
  8. Patrick SteinhardtApr 4, 2024
  9. 5/9 reftable/writer: refactorings for `writer_add_record()`Patrick Steinhardt, Apr 2, 2024
  10. 6/9 reftable/writer: refactorings for `writer_flush_nonempty_block()`Patrick Steinhardt, Apr 2, 2024
  11. 7/9 reftable/block: reuse zstream when writing log blocksPatrick Steinhardt, Apr 2, 2024
  12. Junio C HamanoApr 3, 2024
  13. Patrick SteinhardtApr 4, 2024
  14. 8/9 reftable/block: reuse compressed arrayPatrick Steinhardt, Apr 2, 2024
  15. 9/9 reftable/writer: reset `last_key` instead of releasing itPatrick Steinhardt, Apr 2, 2024
  16. 00/11 reftable: optimize write performancePatrick Steinhardt, Apr 4, 2024
  17. 01/11 refs/reftable: fix D/F conflict error message on ref copyPatrick Steinhardt, Apr 4, 2024
  18. 02/11 refs/reftable: perform explicit D/F check when writing symrefsPatrick Steinhardt, Apr 4, 2024
  19. 03/11 refs/reftable: skip duplicate name checksPatrick Steinhardt, Apr 4, 2024
  20. 04/11 reftable: remove name checksPatrick Steinhardt, Apr 4, 2024
  21. 05/11 refs/reftable: don't recompute committer identPatrick Steinhardt, Apr 4, 2024
  22. 06/11 reftable/writer: refactorings for `writer_add_record()`Patrick Steinhardt, Apr 4, 2024
  23. Han-Wen NienhuysApr 4, 2024
  24. Patrick SteinhardtApr 4, 2024
  25. 07/11 reftable/writer: refactorings for `writer_flush_nonempty_block()`Patrick Steinhardt, Apr 4, 2024
  26. 08/11 reftable/writer: unify releasing memoryPatrick Steinhardt, Apr 4, 2024
  27. Han-Wen NienhuysApr 4, 2024
  28. Patrick SteinhardtApr 4, 2024
  29. Han-Wen NienhuysApr 4, 2024
  30. Patrick SteinhardtApr 4, 2024
  31. 09/11 reftable/writer: reset `last_key` instead of releasing itPatrick Steinhardt, Apr 4, 2024
  32. 10/11 reftable/block: reuse zstream when writing log blocksPatrick Steinhardt, Apr 4, 2024
  33. 11/11 reftable/block: reuse compressed arrayPatrick Steinhardt, Apr 4, 2024
  34. Han-Wen NienhuysApr 4, 2024
  35. Patrick SteinhardtApr 4, 2024
  36. 00/11 reftable: optimize write performancePatrick Steinhardt, Apr 8, 2024
  37. 01/11 refs/reftable: fix D/F conflict error message on ref copyPatrick Steinhardt, Apr 8, 2024
  38. 02/11 refs/reftable: perform explicit D/F check when writing symrefsPatrick Steinhardt, Apr 8, 2024
  39. 03/11 refs/reftable: skip duplicate name checksPatrick Steinhardt, Apr 8, 2024
  40. 04/11 reftable: remove name checksPatrick Steinhardt, Apr 8, 2024
  41. 05/11 refs/reftable: don't recompute committer identPatrick Steinhardt, Apr 8, 2024
  42. 06/11 reftable/writer: refactorings for `writer_add_record()`Patrick Steinhardt, Apr 8, 2024
  43. 07/11 reftable/writer: refactorings for `writer_flush_nonempty_block()`Patrick Steinhardt, Apr 8, 2024
  44. 08/11 reftable/writer: unify releasing memoryPatrick Steinhardt, Apr 8, 2024
  45. 09/11 reftable/writer: reset `last_key` instead of releasing itPatrick Steinhardt, Apr 8, 2024
  46. 10/11 reftable/block: reuse zstream when writing log blocksPatrick Steinhardt, Apr 8, 2024
  47. 11/11 reftable/block: reuse compressed arrayPatrick Steinhardt, Apr 8, 2024
  48. Junio C HamanoApr 9, 2024
  49. Patrick SteinhardtApr 9, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.