PERF: limit time spent diffing large blobs of text

REFACTOR: s/.length/.size/g
This commit is contained in:
Régis Hanol
2019-06-27 01:45:52 +02:00
parent 50e4ecc77e
commit 134a4c66b7
4 changed files with 34 additions and 24 deletions

View File

@@ -1,12 +1,13 @@
# frozen_string_literal: true
# Use "An O(NP) Sequence Comparison Algorithm" as described by Sun Wu, Udi Manber and Gene Myers
# in http://www.itu.dk/stud/speciale/bepjea/xwebtex/litt/an-onp-sequence-comparison-algorithm.pdf
# in https://publications.mpi-cbg.de/Wu_1990_6334.pdf
class ONPDiff
def initialize(a, b)
@a, @b = a, b
@m, @n = a.length, b.length
@m, @n = a.size, b.size
@backtrack = []
if @reverse = @m > @n
@a, @b = @b, @a
@@ -30,13 +31,15 @@ class ONPDiff
return @shortest_path if @shortest_path
size = @m + @n + 3
fp = Array.new(size) { |i| -1 }
@path = Array.new(size) { |i| -1 }
fp = Array.new(size, -1)
@path = Array.new(size, -1)
p = -1
begin
p += 1
return (@shortest_path = []) if p >= 1000
k = -p
while k <= @delta - 1
fp[k + @offset] = snake(k, fp[k - 1 + @offset] + 1, fp[k + 1 + @offset])
@@ -56,6 +59,7 @@ class ONPDiff
r = @path[@delta + @offset]
@shortest_path = []
while r != -1
@shortest_path << [@backtrack[r][0], @backtrack[r][1]]
r = @backtrack[r][2]
@@ -74,7 +78,7 @@ class ONPDiff
y += 1
end
@path[k + @offset] = @backtrack.length
@path[k + @offset] = @backtrack.size
@backtrack << [x, y, r]
y
@@ -84,7 +88,7 @@ class ONPDiff
ses = []
x, y = 1, 1
px, py = 0, 0
i = shortest_path.length - 1
i = shortest_path.size - 1
while i >= 0
while px < shortest_path[i][0] || py < shortest_path[i][1]
if shortest_path[i][1] - shortest_path[i][0] > py - px
@@ -114,12 +118,12 @@ class ONPDiff
ses = []
x, y = 1, 1
px, py = 0, 0
i = shortest_path.length - 1
i = shortest_path.size - 1
while i >= 0
while px < shortest_path[i][0] || py < shortest_path[i][1]
if shortest_path[i][1] - shortest_path[i][0] > py - px
t = @reverse ? :delete : :add
if ses.length > 0 && ses[-1][1] == t
if ses.size > 0 && ses[-1][1] == t
ses[-1][0] << @b[py]
else
ses << [@b[py], t]
@@ -128,7 +132,7 @@ class ONPDiff
py += 1
elsif shortest_path[i][1] - shortest_path[i][0] < py - px
t = @reverse ? :add : :delete
if ses.length > 0 && ses[-1][1] == t
if ses.size > 0 && ses[-1][1] == t
ses[-1][0] << @a[px]
else
ses << [@a[px], t]
@@ -136,7 +140,7 @@ class ONPDiff
x += 1
px += 1
else
if ses.length > 0 && ses[-1][1] == :common
if ses.size > 0 && ses[-1][1] == :common
ses[-1][0] << @a[px]
else
ses << [@a[px], :common]