Mercurial > hg
comparison mercurial/parsers.c @ 27592:7c9eb2927879
dirstate: add a C implementation for nonnormalentries
Before this patch, there was only a python version of nonnormalentries.
On mozilla-central we have a 10x win by putting this function in C:
% python -m timeit -s \
'from mercurial import hg, ui, parsers; \
repo = hg.repository(ui.ui(), "mozilla-central"); \
m = repo.dirstate._map' \
'parsers.nonnormalentries(m)'
100 loops, best of 3: 3.15 msec per loop
The python implementation runs in 31ms, a similar test gives:
10 loops, best of 3: 31.7 msec per loop
On our big repos, the win is still of 10x with the python implementation running
in 350ms and the C implementation running in 30ms.
author | Laurent Charignon <lcharignon@fb.com> |
---|---|
date | Mon, 21 Dec 2015 16:27:16 -0800 |
parents | 41127e875758 |
children | 90e3c5129226 |
comparison
equal
deleted
inserted
replaced
27591:127cc7f78475 | 27592:7c9eb2927879 |
---|---|
545 Py_XDECREF(parents); | 545 Py_XDECREF(parents); |
546 return ret; | 546 return ret; |
547 } | 547 } |
548 | 548 |
549 /* | 549 /* |
550 * Build a set of non-normal entries from the dirstate dmap | |
551 */ | |
552 static PyObject *nonnormalentries(PyObject *self, PyObject *args) | |
553 { | |
554 PyObject *dmap, *nonnset = NULL, *fname, *v; | |
555 Py_ssize_t pos; | |
556 | |
557 if (!PyArg_ParseTuple(args, "O!:nonnormalentries", | |
558 &PyDict_Type, &dmap)) | |
559 goto bail; | |
560 | |
561 nonnset = PySet_New(NULL); | |
562 if (nonnset == NULL) | |
563 goto bail; | |
564 | |
565 pos = 0; | |
566 while (PyDict_Next(dmap, &pos, &fname, &v)) { | |
567 dirstateTupleObject *t; | |
568 if (!dirstate_tuple_check(v)) { | |
569 PyErr_SetString(PyExc_TypeError, | |
570 "expected a dirstate tuple"); | |
571 goto bail; | |
572 } | |
573 t = (dirstateTupleObject *)v; | |
574 | |
575 if (t->state == 'n' && t->mtime != -1) | |
576 continue; | |
577 if (PySet_Add(nonnset, fname) == -1) | |
578 goto bail; | |
579 } | |
580 | |
581 return nonnset; | |
582 bail: | |
583 Py_XDECREF(nonnset); | |
584 return NULL; | |
585 } | |
586 | |
587 /* | |
550 * Efficiently pack a dirstate object into its on-disk format. | 588 * Efficiently pack a dirstate object into its on-disk format. |
551 */ | 589 */ |
552 static PyObject *pack_dirstate(PyObject *self, PyObject *args) | 590 static PyObject *pack_dirstate(PyObject *self, PyObject *args) |
553 { | 591 { |
554 PyObject *packobj = NULL; | 592 PyObject *packobj = NULL; |
2738 PyObject *pathencode(PyObject *self, PyObject *args); | 2776 PyObject *pathencode(PyObject *self, PyObject *args); |
2739 PyObject *lowerencode(PyObject *self, PyObject *args); | 2777 PyObject *lowerencode(PyObject *self, PyObject *args); |
2740 | 2778 |
2741 static PyMethodDef methods[] = { | 2779 static PyMethodDef methods[] = { |
2742 {"pack_dirstate", pack_dirstate, METH_VARARGS, "pack a dirstate\n"}, | 2780 {"pack_dirstate", pack_dirstate, METH_VARARGS, "pack a dirstate\n"}, |
2781 {"nonnormalentries", nonnormalentries, METH_VARARGS, | |
2782 "create a set containing non-normal entries of given dirstate\n"}, | |
2743 {"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"}, | 2783 {"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"}, |
2744 {"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"}, | 2784 {"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"}, |
2745 {"parse_index2", parse_index2, METH_VARARGS, "parse a revlog index\n"}, | 2785 {"parse_index2", parse_index2, METH_VARARGS, "parse a revlog index\n"}, |
2746 {"asciilower", asciilower, METH_VARARGS, "lowercase an ASCII string\n"}, | 2786 {"asciilower", asciilower, METH_VARARGS, "lowercase an ASCII string\n"}, |
2747 {"asciiupper", asciiupper, METH_VARARGS, "uppercase an ASCII string\n"}, | 2787 {"asciiupper", asciiupper, METH_VARARGS, "uppercase an ASCII string\n"}, |