Commit Graph

13 Commits

Author SHA1 Message Date
Gregory Szorc
c8dd79852f revlog: address review feedback for deltachain C implementation
* Scope of "value" is reduced
* index_baserev() is documented
* Error is no longer redundantly set for -2 return values
* Error values are compared <= -2 instead of == -2 to protect
  against odd failure scenarios
2017-07-01 19:35:17 -07:00
Gregory Szorc
c45a2cb5ab revlog: C implementation of delta chain resolution
I've seen revlog._deltachain() appear in a number of performance
profiles. I suspect there are 2 reasons for this:

1. Delta chain resolution performs many index lookups, thus triggering
   population of index tuples. Creating possibly tens of thousands of
   PyObject will have overhead.
2. Delta chain resolution is a tight loop.

By moving delta chain resolution to C, we can defer instantiation
of full index entry tuples and make the loop faster courtesy of
not running in Python.

We can measure the impact to delta chain resolution via
`hg perflogrevision` using the mozilla-central repo with a recent
manifest having delta chain length of 33726:

$ hg perfrevlogrevision -m 364895
! full
! wall 0.367585 comb 0.370000 user 0.340000 sys 0.030000 (best of 27)
! wall 0.357581 comb 0.360000 user 0.350000 sys 0.010000 (best of 28)
! deltachain
! wall 0.010644 comb 0.010000 user 0.010000 sys 0.000000 (best of 270)
! wall 0.000292 comb 0.000000 user 0.000000 sys 0.000000 (best of 8729)

$ hg perfrevlogrevision --cache -m 364895
! deltachain
! wall 0.003904 comb 0.000000 user 0.000000 sys 0.000000 (best of 712)
! wall 0.000284 comb 0.000000 user 0.000000 sys 0.000000 (best of 9926)

The first test measures savings from both not instantiating index
entries and moving to C. The second test (which doesn't clear the
index caches) essentially isolates the benefits of moving from Python
to C. It still shows a 13.7x speedup (versus 36.4x). And there are
multiple milliseconds of savings within the critical path for resolving
revision data. I think that justifies the existence of C code.

A more striking example of the benefits of this change can be
demonstrated by timing `hg debugdeltachain -m` for the mozilla-central
repo:

$ time hg debugdeltachain -m > /dev/null
before:        1057.4s
after:          503.3s
PyPy2.7 5.8.0:  220.0s

It's worth noting that the C code isn't as optimal as it could be.
We're still instantiating a new PyObject for every revision. A future
optimization would be to reuse the PyObject on the cached index tuple.
We could potentially also get wins by using a memory array of raw
integers. There is also room for a delta chain cache on revlog
instances. Of course, the best optimization is to implement revlog
reading outside of Python so Python doesn't need to be concerned
about the relatively expensive index entries and operations on them.
2017-06-25 12:41:34 -07:00
Yuya Nishihara
c8c29352a4 cext: mark constant variables 2017-05-21 13:41:01 +09:00
Yuya Nishihara
79ebd14e1e cext: move util.h to cext tree
Since util.h isn't useful in plain C module, it should be placed in CPython
extension directory.
2017-05-21 13:35:19 +09:00
Yuya Nishihara
0174b4e600 cext: move back finalization of dirstateTupleType where it should be 2017-05-21 13:31:27 +09:00
Gregory Szorc
9e19911eaa cext: extract revlog/index parsing code to own C file
parsers.c is ~3000 lines and ~2/3 of it is related to the revlog
index type.

We already have separate C source files for directory utilities
and manifest parsing. I think the quite unwieldy revlog/index
parsing code should be self-contained as well.

I performed the extraction as a file copy then removed content
from both sides in order to preserve file history and blame.

As part of this, I also had to move the hexdigit table and
function to a shared header since it is used by both parsers.c
and revlog.c

# no-check-commit
2017-05-20 14:01:05 -07:00
Yuya Nishihara
4563e16232 parsers: switch to policy importer
# no-check-commit
2016-08-13 12:23:56 +09:00
Yuya Nishihara
5fe7742660 mpatch: switch to policy importer 2016-08-13 12:18:58 +09:00
Yuya Nishihara
6130be9a6c diffhelpers: switch to policy importer
# no-check-commit
2016-08-13 12:15:49 +09:00
Yuya Nishihara
50b316b748 bdiff: switch to policy importer
# no-check-commit
2016-08-13 12:12:50 +09:00
Yuya Nishihara
a9b78ccb21 base85: switch to policy importer 2016-08-13 12:08:23 +09:00
Yuya Nishihara
70995f9aa9 osutil: switch to policy importer
"make clean" is recommended to test this change, though C API compatibility
should be preserved.
2016-08-12 11:35:17 +09:00
Yuya Nishihara
276d62703a policy: add "cext" package which will host CPython extension modules
I'm going to restructure cext/pure modules and get rid of our hgimporter
hack. C extension modules will be moved to cext/ directory so old and new
compiled modules can coexist in development tree. This is necessary to
run 'hg bisect' without recompiling.

New extension modules will be loaded by an importer function:

  base85 = policy.importmod('base85')  # select pure.base85 or cext.base85

This will also allow us to split cffi from pure modules, which is currently
difficult because pure modules can't be imported by name.
2016-08-12 11:06:14 +09:00