Skip to content

Commit c6f74d9

Browse files
committed
Refactor diffHalfMatchI and remove concat
- The variable j is just a loop index so use a for-loop - Most indentations can be removed by doing early-exits - By doing the concatenating of bestCommon later we can often save lots of cycles - "concat" is useless since in most parts of the code, it isn't used either Fixes #46
1 parent 886a402 commit c6f74d9

File tree

1 file changed

+30
-39
lines changed

1 file changed

+30
-39
lines changed

diffmatchpatch/dmp.go

+30-39
Original file line numberDiff line numberDiff line change
@@ -798,60 +798,51 @@ func (dmp *DiffMatchPatch) diffHalfMatch(text1, text2 []rune) [][]rune {
798798
return [][]rune{hm[2], hm[3], hm[0], hm[1], hm[4]}
799799
}
800800

801-
// diffHalfMatchI checks if a substring of shorttext exist within longtext such that the substring is at least half the length of longtext?
801+
// diffHalfMatchI checks if a substring of shorttext exist within longtext such that the substring is at least half the length of longtext?
802802
// @param {string} longtext Longer string.
803803
// @param {string} shorttext Shorter string.
804804
// @param {number} i Start index of quarter length substring within longtext.
805805
// @return {Array.<string>} Five element Array, containing the prefix of
806806
// longtext, the suffix of longtext, the prefix of shorttext, the suffix
807807
// of shorttext and the common middle. Or null if there was no match.
808808
func (dmp *DiffMatchPatch) diffHalfMatchI(l, s []rune, i int) [][]rune {
809+
var bestCommonA []rune
810+
var bestCommonB []rune
811+
var bestCommonLen int
812+
var bestLongtextA []rune
813+
var bestLongtextB []rune
814+
var bestShorttextA []rune
815+
var bestShorttextB []rune
816+
809817
// Start with a 1/4 length substring at position i as a seed.
810818
seed := l[i : i+len(l)/4]
811-
j := -1
812-
bestCommon := []rune{}
813-
bestLongtextA := []rune{}
814-
bestLongtextB := []rune{}
815-
bestShorttextA := []rune{}
816-
bestShorttextB := []rune{}
817-
818-
if j < len(s) {
819-
j = runesIndexOf(s, seed, j+1)
820-
for {
821-
if j == -1 {
822-
break
823-
}
824819

825-
prefixLength := commonPrefixLength(l[i:], s[j:])
826-
suffixLength := commonSuffixLength(l[:i], s[:j])
827-
if len(bestCommon) < suffixLength+prefixLength {
828-
bestCommon = concat(s[j-suffixLength:j], s[j:j+prefixLength])
829-
bestLongtextA = l[:i-suffixLength]
830-
bestLongtextB = l[i+prefixLength:]
831-
bestShorttextA = s[:j-suffixLength]
832-
bestShorttextB = s[j+prefixLength:]
833-
}
834-
j = runesIndexOf(s, seed, j+1)
820+
for j := runesIndexOf(s, seed, 0); j != -1; j = runesIndexOf(s, seed, j+1) {
821+
prefixLength := commonPrefixLength(l[i:], s[j:])
822+
suffixLength := commonSuffixLength(l[:i], s[:j])
823+
824+
if bestCommonLen < suffixLength+prefixLength {
825+
bestCommonA = s[j-suffixLength : j]
826+
bestCommonB = s[j : j+prefixLength]
827+
bestCommonLen = len(bestCommonA) + len(bestCommonB)
828+
bestLongtextA = l[:i-suffixLength]
829+
bestLongtextB = l[i+prefixLength:]
830+
bestShorttextA = s[:j-suffixLength]
831+
bestShorttextB = s[j+prefixLength:]
835832
}
836833
}
837834

838-
if len(bestCommon)*2 >= len(l) {
839-
return [][]rune{
840-
bestLongtextA,
841-
bestLongtextB,
842-
bestShorttextA,
843-
bestShorttextB,
844-
bestCommon,
845-
}
835+
if bestCommonLen*2 < len(l) {
836+
return nil
846837
}
847-
return nil
848-
}
849838

850-
func concat(r1, r2 []rune) []rune {
851-
result := make([]rune, len(r1)+len(r2))
852-
copy(result, r1)
853-
copy(result[len(r1):], r2)
854-
return result
839+
return [][]rune{
840+
bestLongtextA,
841+
bestLongtextB,
842+
bestShorttextA,
843+
bestShorttextB,
844+
append(bestCommonA, bestCommonB...),
845+
}
855846
}
856847

857848
// DiffCleanupSemantic reduces the number of edits by eliminating

0 commit comments

Comments
 (0)