Skip to content

Commit

Permalink
Remove more nested appends
Browse files Browse the repository at this point in the history
Nested appends generally lead to
unnecessary allocation and copying.

Unwind them in diffCompute.

Replace them in DiffCleanupSemantics with splice.

DiffHalfMatch-8               107µs ± 0%     108µs ± 1%   +0.70%  (p=0.000 n=10+10)
DiffCleanupSemantic-8        1.00ms ± 2%    0.97ms ± 0%   -2.71%  (p=0.000 n=10+8)
DiffMain-8                    1.01s ± 0%     1.01s ± 0%     ~     (p=0.236 n=8+9)
DiffMainLarge-8               110ms ± 1%     110ms ± 1%     ~     (p=1.000 n=9+8)
DiffMainRunesLargeLines-8     692µs ± 1%     693µs ± 1%     ~     (p=0.762 n=10+8)

name                       old alloc/op   new alloc/op   delta
DiffHalfMatch-8               106kB ± 0%     106kB ± 0%     ~     (all equal)
DiffCleanupSemantic-8         255kB ± 0%     177kB ± 0%  -30.76%  (p=0.000 n=9+10)
DiffMain-8                   16.4MB ± 0%    16.4MB ± 0%     ~     (all equal)
DiffMainLarge-8              4.84MB ± 0%    4.81MB ± 0%   -0.57%  (p=0.000 n=10+10)
DiffMainRunesLargeLines-8     175kB ± 0%     174kB ± 0%   -0.34%  (p=0.000 n=10+10)

name                       old allocs/op  new allocs/op  delta
DiffHalfMatch-8                2.00 ± 0%      2.00 ± 0%     ~     (all equal)
DiffCleanupSemantic-8         3.13k ± 0%     3.12k ± 0%   -0.06%  (p=0.000 n=10+10)
DiffMain-8                     83.0 ± 0%      83.0 ± 0%     ~     (all equal)
DiffMainLarge-8               46.5k ± 0%     46.3k ± 0%   -0.41%  (p=0.000 n=10+10)
DiffMainRunesLargeLines-8     1.09k ± 0%     1.08k ± 0%   -0.83%  (p=0.000 n=9+10)
  • Loading branch information
josharian committed Nov 13, 2017
1 parent 6991d24 commit 258a5e0
Showing 1 changed file with 8 additions and 14 deletions.
22 changes: 8 additions & 14 deletions diffmatchpatch/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,10 @@ func (dmp *DiffMatchPatch) diffCompute(text1, text2 []rune, checklines bool, dea
diffsA := dmp.diffMainRunes(text1A, text2A, checklines, deadline)
diffsB := dmp.diffMainRunes(text1B, text2B, checklines, deadline)
// Merge the results.
return append(diffsA, append([]Diff{Diff{DiffEqual, string(midCommon)}}, diffsB...)...)
diffs := diffsA
diffs = append(diffs, Diff{DiffEqual, string(midCommon)})
diffs = append(diffs, diffsB...)
return diffs
} else if checklines && len(text1) > 100 && len(text2) > 100 {
return dmp.diffLineMode(text1, text2, deadline)
}
Expand Down Expand Up @@ -685,9 +688,7 @@ func (dmp *DiffMatchPatch) DiffCleanupSemantic(diffs []Diff) []Diff {
(len(lastequality) <= difference2) {
// Duplicate record.
insPoint := equalities.data
diffs = append(
diffs[:insPoint],
append([]Diff{Diff{DiffDelete, lastequality}}, diffs[insPoint:]...)...)
diffs = splice(diffs, insPoint, 0, Diff{DiffDelete, lastequality})

// Change second copy to insert.
diffs[insPoint+1].Type = DiffInsert
Expand Down Expand Up @@ -738,10 +739,7 @@ func (dmp *DiffMatchPatch) DiffCleanupSemantic(diffs []Diff) []Diff {
float64(overlapLength1) >= float64(len(insertion))/2 {

// Overlap found. Insert an equality and trim the surrounding edits.
diffs = append(
diffs[:pointer],
append([]Diff{Diff{DiffEqual, insertion[:overlapLength1]}}, diffs[pointer:]...)...)

diffs = splice(diffs, pointer, 0, Diff{DiffEqual, insertion[:overlapLength1]})
diffs[pointer-1].Text =
deletion[0 : len(deletion)-overlapLength1]
diffs[pointer+1].Text = insertion[overlapLength1:]
Expand All @@ -752,10 +750,7 @@ func (dmp *DiffMatchPatch) DiffCleanupSemantic(diffs []Diff) []Diff {
float64(overlapLength2) >= float64(len(insertion))/2 {
// Reverse overlap found. Insert an equality and swap and trim the surrounding edits.
overlap := Diff{DiffEqual, deletion[:overlapLength2]}
diffs = append(
diffs[:pointer],
append([]Diff{overlap}, diffs[pointer:]...)...)

diffs = splice(diffs, pointer, 0, overlap)
diffs[pointer-1].Type = DiffInsert
diffs[pointer-1].Text = insertion[0 : len(insertion)-overlapLength2]
diffs[pointer+1].Type = DiffDelete
Expand Down Expand Up @@ -968,8 +963,7 @@ func (dmp *DiffMatchPatch) DiffCleanupEfficiency(diffs []Diff) []Diff {
insPoint := equalities.data

// Duplicate record.
diffs = append(diffs[:insPoint],
append([]Diff{Diff{DiffDelete, lastequality}}, diffs[insPoint:]...)...)
diffs = splice(diffs, insPoint, 0, Diff{DiffDelete, lastequality})

// Change second copy to insert.
diffs[insPoint+1].Type = DiffInsert
Expand Down

0 comments on commit 258a5e0

Please sign in to comment.