Skip to content

Commit 835f45b

Browse files
pftgclaude
andcommitted
perf: eliminate array allocations in ChunkyPNG shift-detection
Replace to_a + product + map + min pattern with nested each loops and running minimum. Zero heap allocations per pixel comparison. Early return on exact match (distance == 0) skips remaining neighborhood. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2512ded commit 835f45b

1 file changed

Lines changed: 16 additions & 14 deletions

File tree

lib/capybara/screenshot/diff/drivers/chunky_png_driver.rb

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -217,22 +217,24 @@ def skipped_region?(x, y)
217217

218218
def color_distance_at(new_img, old_img, x, y, shift_distance_limit:)
219219
org_color = old_img[x, y]
220-
if shift_distance_limit
221-
start_x = [0, x - shift_distance_limit].max
222-
end_x = [x + shift_distance_limit, new_img.width - 1].min
223-
xs = (start_x..end_x).to_a
224-
start_y = [0, y - shift_distance_limit].max
225-
end_y = [y + shift_distance_limit, new_img.height - 1].min
226-
ys = (start_y..end_y).to_a
227-
new_pixels = xs.product(ys)
228-
229-
distances = new_pixels.map do |dx, dy|
230-
ChunkyPNG::Color.euclidean_distance_rgba(org_color, new_img[dx, dy])
220+
unless shift_distance_limit
221+
return ChunkyPNG::Color.euclidean_distance_rgba(org_color, new_img[x, y])
222+
end
223+
224+
start_x = [0, x - shift_distance_limit].max
225+
end_x = [x + shift_distance_limit, new_img.width - 1].min
226+
start_y = [0, y - shift_distance_limit].max
227+
end_y = [y + shift_distance_limit, new_img.height - 1].min
228+
229+
min_distance = Float::INFINITY
230+
(start_y..end_y).each do |dy|
231+
(start_x..end_x).each do |dx|
232+
distance = ChunkyPNG::Color.euclidean_distance_rgba(org_color, new_img[dx, dy])
233+
return 0 if distance == 0
234+
min_distance = distance if distance < min_distance
231235
end
232-
distances.min
233-
else
234-
ChunkyPNG::Color.euclidean_distance_rgba(org_color, new_img[x, y])
235236
end
237+
min_distance
236238
end
237239

238240
def shift_distance_at(new_img, old_img, x, y, color_distance_limit:)

0 commit comments

Comments
 (0)