[Rpm-maint] [PATCH 4/5] Optimize readLine routine
Alexey Tourbin
alexey.tourbin at gmail.com
Tue Feb 5 04:31:38 UTC 2013
This change introduces the following optimizations:
- Line chunking used to be done with per-character loop; it now uses
strchr(line, '\n') call.
- Likewise, the "balancing check" has been enhanced with strpbrk(3).
Callgrind annotations for 'rpmspec -P glibc.spec', previous commit:
94,796,525 PROGRAM TOTALS
33,242,383 rpmio/argv.c:argvCount
9,886,925 build/parseSpec.c:readLine
3,964,158 glibc-2.16-75f0d304/malloc/malloc.c:_int_malloc
...
Callgrind annotations for 'rpmspec -P glibc.spec', this commit:
88,013,018 PROGRAM TOTALS
33,242,383 rpmio/argv.c:argvCount
3,964,158 glibc-2.16-75f0d304/malloc/malloc.c:_int_malloc
...
---
build/parseSpec.c | 66 ++++++++++++++++++++++++++++++++-----------------------
1 file changed, 38 insertions(+), 28 deletions(-)
diff --git a/build/parseSpec.c b/build/parseSpec.c
index 9429454..6cd6bc0 100644
--- a/build/parseSpec.c
+++ b/build/parseSpec.c
@@ -290,23 +290,30 @@ static int copyNextLineFromOFI(rpmSpec spec, OFI_t *ofi)
{
/* Expand next line from file into line buffer */
if (!(spec->nextline && *spec->nextline)) {
- int pc = 0, bc = 0, nc = 0;
const char *from = ofi->readPtr;
- char ch = ' ';
- while (from && *from && ch != '\n') {
- ch = spec->lbuf[spec->lbufOff] = *from;
- spec->lbufOff++; from++;
-
- if (spec->lbufOff >= spec->lbufSize) {
- spec->lbufSize += BUFSIZ;
- spec->lbuf = realloc(spec->lbuf, spec->lbufSize);
- }
+ const char *end = strchr(from, '\n');
+ size_t len;
+ if (end == NULL) {
+ len = strlen(from);
+ end = from + len;
+ }
+ else {
+ end++; /* grab newline */
+ len = end - from;
+ }
+ if (len + 1 > spec->lbufSize - spec->lbufOff) {
+ spec->lbufSize += BUFSIZ + len + 1;
+ spec->lbuf = xrealloc(spec->lbuf, spec->lbufSize);
}
+ memcpy(spec->lbuf + spec->lbufOff, from, len);
+ spec->lbufOff += len;
spec->lbuf[spec->lbufOff] = '\0';
- ofi->readPtr = from;
+ ofi->readPtr = end;
/* Check if we need another line before expanding the buffer. */
- for (const char *p = spec->lbuf; *p; p++) {
+ int pc = 0, bc = 0, nc = 0;
+ for (const char *p = spec->lbuf;
+ (p = strpbrk(p, "\\\n%{}()")) != NULL; p++)
switch (*p) {
case '\\':
switch (*(p+1)) {
@@ -328,7 +335,6 @@ static int copyNextLineFromOFI(rpmSpec spec, OFI_t *ofi)
case '(': if (pc > 0) pc++; break;
case ')': if (pc > 0) pc--; break;
}
- }
/* If it doesn't, ask for one more line. */
if (pc || bc || nc ) {
@@ -359,22 +365,23 @@ static int copyNextLineFromOFI(rpmSpec spec, OFI_t *ofi)
return 0;
}
+/* Logical chunking into lines after macro expansion */
static void copyNextLineFinish(rpmSpec spec, int strip)
{
- char *last;
- char ch;
-
- /* Find next line in expanded line buffer */
- spec->line = last = spec->nextline;
- ch = ' ';
- while (*spec->nextline && ch != '\n') {
- ch = *spec->nextline++;
- if (!risspace(ch))
- last = spec->nextline;
+ /* This line is to be processed */
+ spec->line = spec->nextline;
+
+ /* Next line is after newline character */
+ char *end = strchr(spec->line, '\n');
+ if (end == NULL) {
+ /* Last line */
+ size_t len = strlen(spec->line);
+ end = spec->line + len;
+ spec->nextline = end;
}
-
- /* Save 1st char of next line in order to terminate current line. */
- if (*spec->nextline != '\0') {
+ else {
+ spec->nextline = end + 1;
+ /* Save 1st char of next line in order to terminate current line */
spec->nextpeekc = *spec->nextline;
*spec->nextline = '\0';
}
@@ -382,8 +389,11 @@ static void copyNextLineFinish(rpmSpec spec, int strip)
if (strip & STRIP_COMMENTS)
handleComments(spec->line);
- if (strip & STRIP_TRAILINGSPACE)
- *last = '\0';
+ if (strip & STRIP_TRAILINGSPACE) {
+ while (end > spec->line && risspace(end[-1]))
+ end--;
+ *end = '\0';
+ }
}
static int readLineFromOFI(rpmSpec spec, OFI_t *ofi)
--
1.8.1
More information about the Rpm-maint
mailing list