Merge branch 'sb/indent-heuristic-optim'
authorJunio C Hamano <gitster@pobox.com>
Fri, 17 Aug 2018 20:09:57 +0000 (13:09 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 17 Aug 2018 20:09:57 +0000 (13:09 -0700)
"git diff --indent-heuristic" had a bad corner case performance.

* sb/indent-heuristic-optim:
xdiff: reduce indent heuristic overhead

1  2 
xdiff/xdiffi.c
diff --combined xdiff/xdiffi.c
index 3e8aff92bc436ee99a698fdd748fb1845e28db8c,91e98ee98690276095026154a21d7890d49ea822..1f1f4a3c7808435f73b0ffd1c35d5b0572516b6c
  
  #include "xinclude.h"
  
 -
 -
  #define XDL_MAX_COST_MIN 256
  #define XDL_HEUR_MIN_COST 256
  #define XDL_LINE_MAX (long)((1UL << (CHAR_BIT * sizeof(long) - 1)) - 1)
  #define XDL_SNAKE_CNT 20
  #define XDL_K_HEUR 4
  
 -
 -
  typedef struct s_xdpsplit {
        long i1, i2;
        int min_lo, min_hi;
  } xdpsplit_t;
  
 -
 -
 -
 -static long xdl_split(unsigned long const *ha1, long off1, long lim1,
 -                    unsigned long const *ha2, long off2, long lim2,
 -                    long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl,
 -                    xdalgoenv_t *xenv);
 -static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2);
 -
 -
 -
 -
 -
  /*
   * See "An O(ND) Difference Algorithm and its Variations", by Eugene Myers.
   * Basically considers a "box" (off1, off2, lim1, lim2) and scan from both
@@@ -574,6 -591,11 +574,11 @@@ static void measure_split(const xdfile_
   */
  #define INDENT_WEIGHT 60
  
+ /*
+  * How far do we slide a hunk at most?
+  */
+ #define INDENT_HEURISTIC_MAX_SLIDING 100
  /*
   * Compute a badness score for the hypothetical split whose measurements are
   * stored in m. The weight factors were determined empirically using the tools and
@@@ -886,7 -908,12 +891,12 @@@ int xdl_change_compact(xdfile_t *xdf, x
                        long shift, best_shift = -1;
                        struct split_score best_score;
  
-                       for (shift = earliest_end; shift <= g.end; shift++) {
+                       shift = earliest_end;
+                       if (g.end - groupsize - 1 > shift)
+                               shift = g.end - groupsize - 1;
+                       if (g.end - INDENT_HEURISTIC_MAX_SLIDING > shift)
+                               shift = g.end - INDENT_HEURISTIC_MAX_SLIDING;
+                       for (; shift <= g.end; shift++) {
                                struct split_measurement m;
                                struct split_score score = {0, 0};