git blame -C -C diffs all entries against the same file. To avoid having to recompute the line hashes for this file over and over again, use the xddiff cache feature to store the hashes in struct origin. Note that because this bypasses the xdi_diff tail trimming, it can return different (but still valid) blame results for certain cases. See http://article.gmane.org/gmane.comp.version-control.git/93112 for more details. This yields another significant speed improvement for some cases: :; time git-blame -M -C -C -p --incremental server.c >/dev/null Before: 48.66user 0.08system 0:48.75elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+36961minor)pagefaults 0swaps After: 29.68user 0.22system 0:29.98elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+37897minor)pagefaults 0swaps Signed-off-by: Brian Downing <bdowning@xxxxxxxxx> --- builtin-blame.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diff --git a/builtin-blame.c b/builtin-blame.c index 66b7d15..3e90668 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -80,6 +80,7 @@ struct origin { int refcnt; struct commit *commit; mmfile_t file; + xdcache_t xdcache; unsigned char blob_sha1[20]; char path[FLEX_ARRAY]; }; @@ -119,6 +120,7 @@ static inline struct origin *origin_incref(struct origin *o) static void origin_decref(struct origin *o) { if (o && --o->refcnt <= 0) { + xdl_cache_free(&o->xdcache); free(o->file.ptr); free(o); } @@ -494,7 +496,8 @@ static int process_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, return 0; } -static struct patch *compare_buffer(mmfile_t *file_p, mmfile_t *file_o, +static struct patch *compare_buffer(mmfile_t *file_p, xdcache_t *cache_p, + mmfile_t *file_o, xdcache_t *cache_o, int context) { struct patch *patch; @@ -504,6 +507,8 @@ static struct patch *compare_buffer(mmfile_t *file_p, mmfile_t *file_o, memset(&xpp, 0, sizeof(xpp)); xpp.flags = xdl_opts; + xpp.mf1_cache = cache_p; + xpp.mf2_cache = cache_o; memset(&xecfg, 0, sizeof(xecfg)); xecfg.ctxlen = context; patch = xmalloc(sizeof(struct patch)); @@ -511,7 +516,7 @@ static struct patch *compare_buffer(mmfile_t *file_p, mmfile_t *file_o, patch->num = 0; xecfg.emit_func = (void (*)())process_diff; ecb.priv = patch; - xdi_diff(file_p, file_o, &xpp, &xecfg, &ecb); + xdl_diff(file_p, file_o, &xpp, &xecfg, &ecb); return patch; } @@ -530,7 +535,8 @@ static struct patch *get_patch(struct origin *parent, struct origin *origin) fill_origin_blob(origin, &file_o); if (!file_p.ptr || !file_o.ptr) return NULL; - patch = compare_buffer(&file_p, &file_o, 0); + patch = compare_buffer(&file_p, &parent->xdcache, + &file_o, &origin->xdcache, 0); num_get_patch++; return patch; } @@ -937,7 +943,7 @@ static void find_copy_in_blob(struct scoreboard *sb, } file_o.size = cp - file_o.ptr; - patch = compare_buffer(file_p, &file_o, 1); + patch = compare_buffer(file_p, &parent->xdcache, &file_o, NULL, 1); /* * file_o is a part of final image we are annotating. -- 1.5.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html