Fossil SCM
Optimize the inner loop of the LCS algorithm for the main diff generator.
Commit
4ab6071145a7fe02a114661ee94ea006f0e44a4e
Parent
030035345c802bb…
1 file changed
+20
-9
+20
-9
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -897,10 +897,15 @@ | ||
| 897 | 897 | *piEX = iSXb + mxLength; |
| 898 | 898 | *piSY = iSYb; |
| 899 | 899 | *piEY = iSYb + mxLength; |
| 900 | 900 | } |
| 901 | 901 | |
| 902 | +/* | |
| 903 | +** Minimum of two values | |
| 904 | +*/ | |
| 905 | +static int minInt(int a, int b){ return a<b ? a : b; } | |
| 906 | + | |
| 902 | 907 | /* |
| 903 | 908 | ** Compare two blocks of text on lines iS1 through iE1-1 of the aFrom[] |
| 904 | 909 | ** file and lines iS2 through iE2-1 of the aTo[] file. Locate a sequence |
| 905 | 910 | ** of lines in these two blocks that are exactly the same. Return |
| 906 | 911 | ** the bounds of the matching sequence. |
| @@ -923,11 +928,13 @@ | ||
| 923 | 928 | int iS2, int iE2, /* Range of lines in p->aTo[] */ |
| 924 | 929 | int *piSX, int *piEX, /* Write p->aFrom[] common segment here */ |
| 925 | 930 | int *piSY, int *piEY /* Write p->aTo[] common segment here */ |
| 926 | 931 | ){ |
| 927 | 932 | double bestScore = -1e30; /* Best score seen so far */ |
| 928 | - int i, j; /* Loop counters */ | |
| 933 | + int i, j, k; /* Loop counters */ | |
| 934 | + int n; /* Loop limit */ | |
| 935 | + DLine *pA, *pB; /* Pointers to lines */ | |
| 929 | 936 | int iSX, iSY, iEX, iEY; /* Current match */ |
| 930 | 937 | double score; /* Current score */ |
| 931 | 938 | int skew; /* How lopsided is the match */ |
| 932 | 939 | int dist; /* Distance of match from center */ |
| 933 | 940 | int mid; /* Center of the span */ |
| @@ -956,20 +963,24 @@ | ||
| 956 | 963 | assert( i>=iSXb && i>=iSXp ); |
| 957 | 964 | if( i<iEXb && j>=iSYb && j<iEYb ) continue; |
| 958 | 965 | if( i<iEXp && j>=iSYp && j<iEYp ) continue; |
| 959 | 966 | iSX = i; |
| 960 | 967 | iSY = j-1; |
| 961 | - while( iSX>iS1 && iSY>iS2 && same_dline(&p->aFrom[iSX-1],&p->aTo[iSY-1]) ){ | |
| 962 | - iSX--; | |
| 963 | - iSY--; | |
| 964 | - } | |
| 968 | + pA = &p->aFrom[iSX-1]; | |
| 969 | + pB = &p->aTo[iSY-1]; | |
| 970 | + n = minInt(iSX-iS1, iSY-iS2); | |
| 971 | + for(k=0; k<n && same_dline(pA,pB); k++, pA--, pB--){} | |
| 972 | + iSX -= k; | |
| 973 | + iSY -= k; | |
| 965 | 974 | iEX = i+1; |
| 966 | 975 | iEY = j; |
| 967 | - while( iEX<iE1 && iEY<iE2 && same_dline(&p->aFrom[iEX],&p->aTo[iEY]) ){ | |
| 968 | - iEX++; | |
| 969 | - iEY++; | |
| 970 | - } | |
| 976 | + pA = &p->aFrom[iEX]; | |
| 977 | + pB = &p->aTo[iEY]; | |
| 978 | + n = minInt(iE1-iEX, iE2-iEY); | |
| 979 | + for(k=0; k<n && same_dline(pA,pB); k++, pA++, pB++){} | |
| 980 | + iEX += k; | |
| 981 | + iEY += k; | |
| 971 | 982 | skew = (iSX-iS1) - (iSY-iS2); |
| 972 | 983 | if( skew<0 ) skew = -skew; |
| 973 | 984 | dist = (iSX+iEX)/2 - mid; |
| 974 | 985 | if( dist<0 ) dist = -dist; |
| 975 | 986 | score = (iEX - iSX) - 0.05*skew - 0.05*dist; |
| 976 | 987 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -897,10 +897,15 @@ | |
| 897 | *piEX = iSXb + mxLength; |
| 898 | *piSY = iSYb; |
| 899 | *piEY = iSYb + mxLength; |
| 900 | } |
| 901 | |
| 902 | /* |
| 903 | ** Compare two blocks of text on lines iS1 through iE1-1 of the aFrom[] |
| 904 | ** file and lines iS2 through iE2-1 of the aTo[] file. Locate a sequence |
| 905 | ** of lines in these two blocks that are exactly the same. Return |
| 906 | ** the bounds of the matching sequence. |
| @@ -923,11 +928,13 @@ | |
| 923 | int iS2, int iE2, /* Range of lines in p->aTo[] */ |
| 924 | int *piSX, int *piEX, /* Write p->aFrom[] common segment here */ |
| 925 | int *piSY, int *piEY /* Write p->aTo[] common segment here */ |
| 926 | ){ |
| 927 | double bestScore = -1e30; /* Best score seen so far */ |
| 928 | int i, j; /* Loop counters */ |
| 929 | int iSX, iSY, iEX, iEY; /* Current match */ |
| 930 | double score; /* Current score */ |
| 931 | int skew; /* How lopsided is the match */ |
| 932 | int dist; /* Distance of match from center */ |
| 933 | int mid; /* Center of the span */ |
| @@ -956,20 +963,24 @@ | |
| 956 | assert( i>=iSXb && i>=iSXp ); |
| 957 | if( i<iEXb && j>=iSYb && j<iEYb ) continue; |
| 958 | if( i<iEXp && j>=iSYp && j<iEYp ) continue; |
| 959 | iSX = i; |
| 960 | iSY = j-1; |
| 961 | while( iSX>iS1 && iSY>iS2 && same_dline(&p->aFrom[iSX-1],&p->aTo[iSY-1]) ){ |
| 962 | iSX--; |
| 963 | iSY--; |
| 964 | } |
| 965 | iEX = i+1; |
| 966 | iEY = j; |
| 967 | while( iEX<iE1 && iEY<iE2 && same_dline(&p->aFrom[iEX],&p->aTo[iEY]) ){ |
| 968 | iEX++; |
| 969 | iEY++; |
| 970 | } |
| 971 | skew = (iSX-iS1) - (iSY-iS2); |
| 972 | if( skew<0 ) skew = -skew; |
| 973 | dist = (iSX+iEX)/2 - mid; |
| 974 | if( dist<0 ) dist = -dist; |
| 975 | score = (iEX - iSX) - 0.05*skew - 0.05*dist; |
| 976 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -897,10 +897,15 @@ | |
| 897 | *piEX = iSXb + mxLength; |
| 898 | *piSY = iSYb; |
| 899 | *piEY = iSYb + mxLength; |
| 900 | } |
| 901 | |
| 902 | /* |
| 903 | ** Minimum of two values |
| 904 | */ |
| 905 | static int minInt(int a, int b){ return a<b ? a : b; } |
| 906 | |
| 907 | /* |
| 908 | ** Compare two blocks of text on lines iS1 through iE1-1 of the aFrom[] |
| 909 | ** file and lines iS2 through iE2-1 of the aTo[] file. Locate a sequence |
| 910 | ** of lines in these two blocks that are exactly the same. Return |
| 911 | ** the bounds of the matching sequence. |
| @@ -923,11 +928,13 @@ | |
| 928 | int iS2, int iE2, /* Range of lines in p->aTo[] */ |
| 929 | int *piSX, int *piEX, /* Write p->aFrom[] common segment here */ |
| 930 | int *piSY, int *piEY /* Write p->aTo[] common segment here */ |
| 931 | ){ |
| 932 | double bestScore = -1e30; /* Best score seen so far */ |
| 933 | int i, j, k; /* Loop counters */ |
| 934 | int n; /* Loop limit */ |
| 935 | DLine *pA, *pB; /* Pointers to lines */ |
| 936 | int iSX, iSY, iEX, iEY; /* Current match */ |
| 937 | double score; /* Current score */ |
| 938 | int skew; /* How lopsided is the match */ |
| 939 | int dist; /* Distance of match from center */ |
| 940 | int mid; /* Center of the span */ |
| @@ -956,20 +963,24 @@ | |
| 963 | assert( i>=iSXb && i>=iSXp ); |
| 964 | if( i<iEXb && j>=iSYb && j<iEYb ) continue; |
| 965 | if( i<iEXp && j>=iSYp && j<iEYp ) continue; |
| 966 | iSX = i; |
| 967 | iSY = j-1; |
| 968 | pA = &p->aFrom[iSX-1]; |
| 969 | pB = &p->aTo[iSY-1]; |
| 970 | n = minInt(iSX-iS1, iSY-iS2); |
| 971 | for(k=0; k<n && same_dline(pA,pB); k++, pA--, pB--){} |
| 972 | iSX -= k; |
| 973 | iSY -= k; |
| 974 | iEX = i+1; |
| 975 | iEY = j; |
| 976 | pA = &p->aFrom[iEX]; |
| 977 | pB = &p->aTo[iEY]; |
| 978 | n = minInt(iE1-iEX, iE2-iEY); |
| 979 | for(k=0; k<n && same_dline(pA,pB); k++, pA++, pB++){} |
| 980 | iEX += k; |
| 981 | iEY += k; |
| 982 | skew = (iSX-iS1) - (iSY-iS2); |
| 983 | if( skew<0 ) skew = -skew; |
| 984 | dist = (iSX+iEX)/2 - mid; |
| 985 | if( dist<0 ) dist = -dist; |
| 986 | score = (iEX - iSX) - 0.05*skew - 0.05*dist; |
| 987 |