Skip to content

Commit f08c8db

Browse files
author
Julien "_FrnchFrgg_" RIVAUD
committed
Speed up findLongestMatch, avoid allocations (string version)
1 parent d3b4782 commit f08c8db

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

difflib/difflib.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,26 +234,43 @@ func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match {
234234
// find longest junk-free match
235235
// during an iteration of the loop, j2len[j] = length of longest
236236
// junk-free match ending with a[i-1] and b[j]
237-
j2len := map[int]int{}
237+
N := bhi - blo
238+
j2len := make([]int, N)
239+
newj2len := make([]int, N)
240+
var indices []int
238241
for i := alo; i != ahi; i++ {
239242
// look at all instances of a[i] in b; note that because
240243
// b2j has no junk keys, the loop is skipped if a[i] is junk
241-
newj2len := map[int]int{}
242-
for _, j := range m.b2j[m.a[i]] {
244+
newindices := m.b2j[m.a[i]]
245+
for _, j := range newindices {
243246
// a[i] matches b[j]
244247
if j < blo {
245248
continue
246249
}
247250
if j >= bhi {
248251
break
249252
}
250-
k := j2len[j-1] + 1
251-
newj2len[j] = k
253+
k := 1
254+
if j > blo {
255+
k = j2len[j-1-blo] + 1
256+
}
257+
newj2len[j-blo] = k
252258
if k > bestsize {
253259
besti, bestj, bestsize = i-k+1, j-k+1, k
254260
}
255261
}
256-
j2len = newj2len
262+
// j2len = newj2len, clear and reuse j2len as newj2len
263+
for _, j := range indices {
264+
if j < blo {
265+
continue
266+
}
267+
if j >= bhi {
268+
break
269+
}
270+
j2len[j-blo] = 0
271+
}
272+
indices = newindices
273+
j2len, newj2len = newj2len, j2len
257274
}
258275

259276
// Extend the best by non-junk elements on each end. In particular,

0 commit comments

Comments
 (0)