comparison mercurial/exchange.py @ 51892:8583d138f436

exchange: improve computation of relevant markers for large repos Compute the candidate nodes with relevant markers directly from keys of the predecessors/successors/children dictionaries of obsstore. This is faster than iterating over all nodes directly. This test could be further improved for repositories with relative few markers compared to the repository size, but this is no longer hot already. With the current loop structure, the obshashrange use works as well as before as it passes lists with a single node. Adjust the interface by allowing revision lists as well as node lists. This helps cases that computes ancestors as it reduces the materialisation cost. Use this in _pushdiscoveryobsmarker and _getbundleobsmarkerpart. Improve the latter further by directly using ancestors(). Performance benchmarks show notable and welcome improvement to no-op push and pull (that would also apply to other push/pull). This apply to push and pull done without evolve. ### push/pull Benchmark parameter # bin-env-vars.hg.flavor = default # benchmark.variants.explicit-rev = none # benchmark.variants.protocol = ssh # benchmark.variants.revs = none ## benchmark.name = hg.command.pull # data-env-vars.name = mercurial-devel-2024-03-22-zstd-sparse-revlog before: 5.968537 seconds after: 5.668507 seconds (-5.03%, -0.30) # data-env-vars.name = tryton-devel-2024-03-22-zstd-sparse-revlog before: 1.446232 seconds after: 0.835553 seconds (-42.23%, -0.61) # data-env-vars.name = netbsd-src-draft-2024-09-19-zstd-sparse-revlog before: 5.777412 seconds after: 2.523454 seconds (-56.32%, -3.25) ## benchmark.name = hg.command.push # data-env-vars.name = mercurial-devel-2024-03-22-zstd-sparse-revlog before: 6.155501 seconds after: 5.885072 seconds (-4.39%, -0.27) # data-env-vars.name = tryton-devel-2024-03-22-zstd-sparse-revlog before: 1.491054 seconds after: 0.934882 seconds (-37.30%, -0.56) # data-env-vars.name = netbsd-src-draft-2024-09-19-zstd-sparse-revlog before: 5.902494 seconds after: 2.957644 seconds (-49.89%, -2.94) There is not notable different in these result using the "rust" flavor instead of the "default". The performance impact on the same operation when using evolve were also tested and no impact was noted.
author Joerg Sonnenberger <joerg@bec.de>
date Mon, 08 Jul 2024 22:46:04 +0200
parents f4733654f144
children aa7f4a45d8fa
comparison
equal deleted inserted replaced
51891:ee7e106b372b 51892:8583d138f436
702 return 702 return
703 703
704 repo = pushop.repo 704 repo = pushop.repo
705 # very naive computation, that can be quite expensive on big repo. 705 # very naive computation, that can be quite expensive on big repo.
706 # However: evolution is currently slow on them anyway. 706 # However: evolution is currently slow on them anyway.
707 nodes = (c.node() for c in repo.set(b'::%ln', pushop.futureheads)) 707 revs = repo.revs(b'::%ln', pushop.futureheads)
708 pushop.outobsmarkers = pushop.repo.obsstore.relevantmarkers(nodes) 708 pushop.outobsmarkers = pushop.repo.obsstore.relevantmarkers(revs=revs)
709 709
710 710
711 @pushdiscovery(b'bookmarks') 711 @pushdiscovery(b'bookmarks')
712 def _pushdiscoverybookmarks(pushop): 712 def _pushdiscoverybookmarks(pushop):
713 ui = pushop.ui 713 ui = pushop.ui
2602 def _getbundleobsmarkerpart( 2602 def _getbundleobsmarkerpart(
2603 bundler, repo, source, bundlecaps=None, b2caps=None, heads=None, **kwargs 2603 bundler, repo, source, bundlecaps=None, b2caps=None, heads=None, **kwargs
2604 ): 2604 ):
2605 """add an obsolescence markers part to the requested bundle""" 2605 """add an obsolescence markers part to the requested bundle"""
2606 if kwargs.get('obsmarkers', False): 2606 if kwargs.get('obsmarkers', False):
2607 unfi_cl = repo.unfiltered().changelog
2607 if heads is None: 2608 if heads is None:
2608 heads = repo.heads() 2609 headrevs = repo.changelog.headrevs()
2609 subset = [c.node() for c in repo.set(b'::%ln', heads)] 2610 else:
2610 markers = repo.obsstore.relevantmarkers(subset) 2611 get_rev = unfi_cl.index.get_rev
2612 headrevs = [get_rev(node) for node in heads]
2613 headrevs = [rev for rev in headrevs if rev is not None]
2614 revs = unfi_cl.ancestors(headrevs, inclusive=True)
2615 markers = repo.obsstore.relevantmarkers(revs=revs)
2611 markers = obsutil.sortedmarkers(markers) 2616 markers = obsutil.sortedmarkers(markers)
2612 bundle2.buildobsmarkerspart(bundler, markers) 2617 bundle2.buildobsmarkerspart(bundler, markers)
2613 2618
2614 2619
2615 @getbundle2partsgenerator(b'phases') 2620 @getbundle2partsgenerator(b'phases')