Mercurial > hg
comparison contrib/perf.py @ 42385:21c436a3a4e8
perf: add a `perfhelper-mergecopies` command
This command gather data that are useful to pick argument for `perfmergecopies`.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 23 May 2019 18:15:08 +0200 |
parents | f5f0a9490c05 |
children | 4372d56112c9 |
comparison
equal
deleted
inserted
replaced
42384:f5f0a9490c05 | 42385:21c436a3a4e8 |
---|---|
1469 | 1469 |
1470 timer, fm = gettimer(ui, opts) | 1470 timer, fm = gettimer(ui, opts) |
1471 timer(format) | 1471 timer(format) |
1472 fm.end() | 1472 fm.end() |
1473 | 1473 |
1474 @command(b'perfhelper-mergecopies', formatteropts + | |
1475 [ | |
1476 (b'r', b'revs', [], b'restrict search to these revisions'), | |
1477 (b'', b'timing', False, b'provides extra data (costly)'), | |
1478 ]) | |
1479 def perfhelpermergecopies(ui, repo, revs=[], **opts): | |
1480 """find statistics about potential parameters for `perfmergecopies` | |
1481 | |
1482 This command find (base, p1, p2) triplet relevant for copytracing | |
1483 benchmarking in the context of a merge. It reports values for some of the | |
1484 parameters that impact merge copy tracing time during merge. | |
1485 | |
1486 If `--timing` is set, rename detection is run and the associated timing | |
1487 will be reported. The extra details come at the cost of slower command | |
1488 execution. | |
1489 | |
1490 Since rename detection is only run once, other factors might easily | |
1491 affect the precision of the timing. However it should give a good | |
1492 approximation of which revision triplets are very costly. | |
1493 """ | |
1494 opts = _byteskwargs(opts) | |
1495 fm = ui.formatter(b'perf', opts) | |
1496 dotiming = opts[b'timing'] | |
1497 | |
1498 output_template = [ | |
1499 ("base", "%(base)12s"), | |
1500 ("p1", "%(p1.node)12s"), | |
1501 ("p2", "%(p2.node)12s"), | |
1502 ("p1.nb-revs", "%(p1.nbrevs)12d"), | |
1503 ("p1.nb-files", "%(p1.nbmissingfiles)12d"), | |
1504 ("p1.renames", "%(p1.renamedfiles)12d"), | |
1505 ("p1.time", "%(p1.time)12.3f"), | |
1506 ("p2.nb-revs", "%(p2.nbrevs)12d"), | |
1507 ("p2.nb-files", "%(p2.nbmissingfiles)12d"), | |
1508 ("p2.renames", "%(p2.renamedfiles)12d"), | |
1509 ("p2.time", "%(p2.time)12.3f"), | |
1510 ("renames", "%(nbrenamedfiles)12d"), | |
1511 ("total.time", "%(time)12.3f"), | |
1512 ] | |
1513 if not dotiming: | |
1514 output_template = [i for i in output_template | |
1515 if not ('time' in i[0] or 'renames' in i[0])] | |
1516 header_names = [h for (h, v) in output_template] | |
1517 output = ' '.join([v for (h, v) in output_template]) + '\n' | |
1518 header = ' '.join(['%12s'] * len(header_names)) + '\n' | |
1519 fm.plain(header % tuple(header_names)) | |
1520 | |
1521 if not revs: | |
1522 revs = ['all()'] | |
1523 revs = scmutil.revrange(repo, revs) | |
1524 | |
1525 roi = repo.revs('merge() and %ld', revs) | |
1526 for r in roi: | |
1527 ctx = repo[r] | |
1528 p1 = ctx.p1() | |
1529 p2 = ctx.p2() | |
1530 bases = repo.changelog._commonancestorsheads(p1.rev(), p2.rev()) | |
1531 for b in bases: | |
1532 b = repo[b] | |
1533 p1missing = copies._computeforwardmissing(b, p1) | |
1534 p2missing = copies._computeforwardmissing(b, p2) | |
1535 data = { | |
1536 b'base': b.hex(), | |
1537 b'p1.node': p1.hex(), | |
1538 b'p1.nbrevs': len(repo.revs('%d::%d', b.rev(), p1.rev())), | |
1539 b'p1.nbmissingfiles': len(p1missing), | |
1540 b'p2.node': p2.hex(), | |
1541 b'p2.nbrevs': len(repo.revs('%d::%d', b.rev(), p2.rev())), | |
1542 b'p2.nbmissingfiles': len(p2missing), | |
1543 } | |
1544 if dotiming: | |
1545 begin = util.timer() | |
1546 mergedata = copies.mergecopies(repo, p1, p2, b) | |
1547 end = util.timer() | |
1548 # not very stable timing since we did only one run | |
1549 data['time'] = end - begin | |
1550 # mergedata contains five dicts: "copy", "movewithdir", | |
1551 # "diverge", "renamedelete" and "dirmove". | |
1552 # The first 4 are about renamed file so lets count that. | |
1553 renames = len(mergedata[0]) | |
1554 renames += len(mergedata[1]) | |
1555 renames += len(mergedata[2]) | |
1556 renames += len(mergedata[3]) | |
1557 data['nbrenamedfiles'] = renames | |
1558 begin = util.timer() | |
1559 p1renames = copies.pathcopies(b, p1) | |
1560 end = util.timer() | |
1561 data['p1.time'] = end - begin | |
1562 begin = util.timer() | |
1563 p2renames = copies.pathcopies(b, p2) | |
1564 data['p2.time'] = end - begin | |
1565 end = util.timer() | |
1566 data['p1.renamedfiles'] = len(p1renames) | |
1567 data['p2.renamedfiles'] = len(p2renames) | |
1568 fm.startitem() | |
1569 fm.data(**data) | |
1570 # make node pretty for the human output | |
1571 out = data.copy() | |
1572 out['base'] = fm.hexfunc(b.node()) | |
1573 out['p1.node'] = fm.hexfunc(p1.node()) | |
1574 out['p2.node'] = fm.hexfunc(p2.node()) | |
1575 fm.plain(output % out) | |
1576 | |
1577 fm.end() | |
1578 | |
1474 @command(b'perfhelper-pathcopies', formatteropts + | 1579 @command(b'perfhelper-pathcopies', formatteropts + |
1475 [ | 1580 [ |
1476 (b'r', b'revs', [], b'restrict search to these revisions'), | 1581 (b'r', b'revs', [], b'restrict search to these revisions'), |
1477 (b'', b'timing', False, b'provides extra data (costly)'), | 1582 (b'', b'timing', False, b'provides extra data (costly)'), |
1478 ]) | 1583 ]) |