diff -r 54421ef8a423 -r f5f113f1b011 mercurial/revlogutils/deltas.py --- a/mercurial/revlogutils/deltas.py Wed Nov 23 21:11:46 2022 -0500 +++ b/mercurial/revlogutils/deltas.py Sun Nov 06 14:47:17 2022 -0500 @@ -680,6 +680,7 @@ good = None deltas_limit = textlen * LIMIT_DELTA2TEXT + group_chunk_size = revlog._candidate_group_chunk_size tested = {nullrev} candidates = _refinedgroups( @@ -770,11 +771,30 @@ group.append(rev) if group: - # XXX: in the sparse revlog case, group can become large, - # impacting performances. Some bounding or slicing mecanism - # would help to reduce this impact. - tested.update(group) - good = yield tuple(group) + # When the size of the candidate group is big, it can result in a + # quite significant performance impact. To reduce this, we can send + # them in smaller batches until the new batch does not provide any + # improvements. + # + # This might reduce the overall efficiency of the compression in + # some corner cases, but that should also prevent very pathological + # cases from being an issue. (eg. 20 000 candidates). + # + # XXX note that the ordering of the group becomes important as it + # now impacts the final result. The current order is unprocessed + # and can be improved. + if group_chunk_size == 0: + tested.update(group) + good = yield tuple(group) + else: + prev_good = good + for start in range(0, len(group), group_chunk_size): + sub_group = group[start : start + group_chunk_size] + tested.update(sub_group) + good = yield tuple(sub_group) + if prev_good == good: + break + yield None