Mercurial > hg
comparison mercurial/dirs.c @ 25016:42e89b87ca79
dirs: speed up by storing number of direct children per dir
The Python version of the dirs type stores only the number of direct
children associated with each directory. That means that while adding
a directory, it only has to walk backwards until it runs into a
directory that is already in its map. The C version walks all the way
to the top-most directory. By copying the Python version's clever
trick to the C code, we can speed it up quite a bit.
On the Firefox repo, perfdirs now runs in 0.031390, from 0.056518
before the undoing Sid's optimization in the previous change, and
0.061835 before previous his optimization. More practically, it speeds
up 'hg status nonexistent' on the Firefox repo from 0.176s to 0.155s.
It's unclear why the C version did not have the same cleverness
implemented from the start, especially given that they were both
written by the same person (Bryan O'Sullivan) very close in time:
856960173630 (scmutil: add a dirs class, 2013-04-10)
02ee846b246a (scmutil: rewrite dirs in C, use if available, 2013-04-10)
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Fri, 08 May 2015 15:04:14 -0700 |
parents | b3a68fb8b859 |
children | f41539418b41 |
comparison
equal
deleted
inserted
replaced
25015:b3a68fb8b859 | 25016:42e89b87ca79 |
---|---|
67 PyString_AS_STRING(key)[pos] = '\0'; | 67 PyString_AS_STRING(key)[pos] = '\0'; |
68 | 68 |
69 val = PyDict_GetItem(dirs, key); | 69 val = PyDict_GetItem(dirs, key); |
70 if (val != NULL) { | 70 if (val != NULL) { |
71 PyInt_AS_LONG(val) += 1; | 71 PyInt_AS_LONG(val) += 1; |
72 continue; | 72 break; |
73 } | 73 } |
74 | 74 |
75 /* Force Python to not reuse a small shared int. */ | 75 /* Force Python to not reuse a small shared int. */ |
76 val = PyInt_FromLong(0x1eadbeef); | 76 val = PyInt_FromLong(0x1eadbeef); |
77 | 77 |
112 PyErr_SetString(PyExc_ValueError, | 112 PyErr_SetString(PyExc_ValueError, |
113 "expected a value, found none"); | 113 "expected a value, found none"); |
114 goto bail; | 114 goto bail; |
115 } | 115 } |
116 | 116 |
117 if (--PyInt_AS_LONG(val) <= 0 && | 117 if (--PyInt_AS_LONG(val) <= 0) { |
118 PyDict_DelItem(dirs, key) == -1) | 118 if (PyDict_DelItem(dirs, key) == -1) |
119 goto bail; | 119 goto bail; |
120 } else | |
121 break; | |
120 Py_CLEAR(key); | 122 Py_CLEAR(key); |
121 } | 123 } |
122 ret = 0; | 124 ret = 0; |
123 | 125 |
124 bail: | 126 bail: |