Skip to content

Commit d3b4782

Browse files
author
Julien "_FrnchFrgg_" RIVAUD
committed
Speed up findLongestMatch by avoiding a lot of allocations
1 parent 81c1f35 commit d3b4782

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

difflib/bytes/bytes.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -294,26 +294,43 @@ func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match {
294294
// find longest junk-free match
295295
// during an iteration of the loop, j2len[j] = length of longest
296296
// junk-free match ending with a[i-1] and b[j]
297-
j2len := map[int]int{}
297+
N := bhi - blo
298+
j2len := make([]int, N)
299+
newj2len := make([]int, N)
300+
var indices []int
298301
for i := alo; i != ahi; i++ {
299302
// look at all instances of a[i] in b; note that because
300303
// b2j has no junk keys, the loop is skipped if a[i] is junk
301-
newj2len := map[int]int{}
302-
for _, j := range m.b2j.get(m.a[i]) {
304+
newindices := m.b2j.get(m.a[i])
305+
for _, j := range newindices {
303306
// a[i] matches b[j]
304307
if j < blo {
305308
continue
306309
}
307310
if j >= bhi {
308311
break
309312
}
310-
k := j2len[j-1] + 1
311-
newj2len[j] = k
313+
k := 1
314+
if j > blo {
315+
k = j2len[j-1-blo] + 1
316+
}
317+
newj2len[j-blo] = k
312318
if k > bestsize {
313319
besti, bestj, bestsize = i-k+1, j-k+1, k
314320
}
315321
}
316-
j2len = newj2len
322+
// j2len = newj2len, clear and reuse j2len as newj2len
323+
for _, j := range indices {
324+
if j < blo {
325+
continue
326+
}
327+
if j >= bhi {
328+
break
329+
}
330+
j2len[j-blo] = 0
331+
}
332+
indices = newindices
333+
j2len, newj2len = newj2len, j2len
317334
}
318335

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

0 commit comments

Comments
 (0)