Use kwset in pickaxe

Benchmarks in the hot cache case: before: $ perf stat --repeat=5 git log -Sqwerty Performance counter stats for 'git log -Sqwerty' (5 runs): 47,092,744 cache-misses # 2.825 M/sec ( +- 1.607% ) 123,368,389 cache-references # 7.400 M/sec ( +- 0.812% ) 330,040,998 branch-misses # 3.134 % ( +- 0.257% ) 10,530,896,750 branches # 631.663 M/sec ( +- 0.121% ) 62,037,201,030 instructions # 1.399 IPC ( +- 0.142% ) 44,331,294,321 cycles # 2659.073 M/sec ( +- 0.326% ) 96,794 page-faults # 0.006 M/sec ( +- 11.952% ) 25 CPU-migrations # 0.000 M/sec ( +- 25.266% ) 1,424 context-switches # 0.000 M/sec ( +- 0.540% ) 16671.708650 task-clock-msecs # 0.997 CPUs ( +- 0.343% ) 16.728692052 seconds time elapsed ( +- 0.344% ) after: $ perf stat --repeat=5 git log -Sqwerty Performance counter stats for 'git log -Sqwerty' (5 runs): 51,385,522 cache-misses # 4.619 M/sec ( +- 0.565% ) 129,177,880 cache-references # 11.611 M/sec ( +- 0.219% ) 319,222,775 branch-misses # 6.946 % ( +- 0.134% ) 4,595,913,233 branches # 413.086 M/sec ( +- 0.112% ) 31,395,042,533 instructions # 1.062 IPC ( +- 0.129% ) 29,558,348,598 cycles # 2656.740 M/sec ( +- 0.204% ) 93,224 page-faults # 0.008 M/sec ( +- 4.487% ) 19 CPU-migrations # 0.000 M/sec ( +- 10.425% ) 950 context-switches # 0.000 M/sec ( +- 0.360% ) 11125.796039 task-clock-msecs # 0.997 CPUs ( +- 0.239% ) 11.164216599 seconds time elapsed ( +- 0.240% ) So the kwset code is about 33% faster. Signed-off-by: Fredrik Kuivinen <frekui@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Fredrik Kuivinen committed Aug 21, 2011 at 00:41 UTC b95c5ada990ee2afb83af9be5b82d2804618a59d
2 files changed +25 -11
Makefile
+2
@@ -533,6 +533,7 @@ LIB_H += graph.h
533 LIB_H += grep.h
534 LIB_H += hash.h
535 LIB_H += help.h
536 +LIB_H += kwset.h
537 LIB_H += levenshtein.h
538 LIB_H += list-objects.h
539 LIB_H += ll-merge.h
@@ -624,6 +625,7 @@ LIB_OBJS += hash.o
625 LIB_OBJS += help.o
626 LIB_OBJS += hex.o
627 LIB_OBJS += ident.o
628 +LIB_OBJS += kwset.o
629 LIB_OBJS += levenshtein.o
630 LIB_OBJS += list-objects.o
631 LIB_OBJS += ll-merge.o
diffcore-pickaxe.c
+23 -11
@@ -6,6 +6,7 @@
6 #include "diff.h"
7 #include "diffcore.h"
8 #include "xdiff-interface.h"
9 +#include "kwset.h"
10
11 struct diffgrep_cb {
12 regex_t *regexp;
@@ -146,7 +147,7 @@ static void diffcore_pickaxe_grep(struct diff_options *o)
147
148 static unsigned int contains(struct diff_filespec *one,
149 const char *needle, unsigned long len,
149 - regex_t *regexp)
150 + regex_t *regexp, kwset_t kws)
151 {
152 unsigned int cnt;
153 unsigned long sz;
@@ -175,9 +176,12 @@ static unsigned int contains(struct diff_filespec *one,
176
177 } else { /* Classic exact string match */
178 while (sz) {
178 - const char *found = memmem(data, sz, needle, len);
179 - if (!found)
179 + size_t offset = kwsexec(kws, data, sz, NULL);
180 + const char *found;
181 + if (offset == -1)
182 break;
183 + else
184 + found = data + offset;
185 sz -= found - data + len;
186 data = found + len;
187 cnt++;
@@ -195,6 +199,7 @@ static void diffcore_pickaxe_count(struct diff_options *o)
199 unsigned long len = strlen(needle);
200 int i, has_changes;
201 regex_t regex, *regexp = NULL;
202 + kwset_t kws = NULL;
203 struct diff_queue_struct outq;
204 DIFF_QUEUE_CLEAR(&outq);
205
@@ -209,6 +214,10 @@ static void diffcore_pickaxe_count(struct diff_options *o)
214 die("invalid pickaxe regex: %s", errbuf);
215 }
216 regexp = &regex;
217 + } else {
218 + kws = kwsalloc(NULL);
219 + kwsincr(kws, needle, len);
220 + kwsprep(kws);
221 }
222
223 if (opts & DIFF_PICKAXE_ALL) {
@@ -219,16 +228,16 @@ static void diffcore_pickaxe_count(struct diff_options *o)
228 if (!DIFF_FILE_VALID(p->two))
229 continue; /* ignore unmerged */
230 /* created */
222 - if (contains(p->two, needle, len, regexp))
231 + if (contains(p->two, needle, len, regexp, kws))
232 has_changes++;
233 }
234 else if (!DIFF_FILE_VALID(p->two)) {
226 - if (contains(p->one, needle, len, regexp))
235 + if (contains(p->one, needle, len, regexp, kws))
236 has_changes++;
237 }
238 else if (!diff_unmodified_pair(p) &&
230 - contains(p->one, needle, len, regexp) !=
231 - contains(p->two, needle, len, regexp))
239 + contains(p->one, needle, len, regexp, kws) !=
240 + contains(p->two, needle, len, regexp, kws))
241 has_changes++;
242 }
243 if (has_changes)
@@ -251,16 +260,17 @@ static void diffcore_pickaxe_count(struct diff_options *o)
260 if (!DIFF_FILE_VALID(p->two))
261 ; /* ignore unmerged */
262 /* created */
254 - else if (contains(p->two, needle, len, regexp))
263 + else if (contains(p->two, needle, len, regexp,
264 + kws))
265 has_changes = 1;
266 }
267 else if (!DIFF_FILE_VALID(p->two)) {
258 - if (contains(p->one, needle, len, regexp))
268 + if (contains(p->one, needle, len, regexp, kws))
269 has_changes = 1;
270 }
271 else if (!diff_unmodified_pair(p) &&
262 - contains(p->one, needle, len, regexp) !=
263 - contains(p->two, needle, len, regexp))
272 + contains(p->one, needle, len, regexp, kws) !=
273 + contains(p->two, needle, len, regexp, kws))
274 has_changes = 1;
275
276 if (has_changes)
@@ -271,6 +281,8 @@ static void diffcore_pickaxe_count(struct diff_options *o)
281
282 if (opts & DIFF_PICKAXE_REGEX)
283 regfree(&regex);
284 + else
285 + kwsfree(kws);
286
287 free(q->queue);
288 *q = outq;