Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precision checking algorithm is very slow #573

Closed
fjcaetano opened this issue Feb 11, 2022 · 6 comments · Fixed by #628
Closed

Precision checking algorithm is very slow #573

fjcaetano opened this issue Feb 11, 2022 · 6 comments · Fixed by #628

Comments

@fjcaetano
Copy link

Describe the bug
When snapshot testing images with precision lower than 1, if the snapshots don't exactly match the reference images, the tests take much longer to run.

We currently have 66 snapshot tests in a framework

Precision Passing Tests Failing Tests Pixel-Imperfect Images Total Time
1 57 9 36 38s
0.97 66 0 36 483s

Those 9 failing unit-tests are recording 4 images each to account for different device sizes, so those 36 images that are not pixel-perfect are responsible for a 12.7x increase in the total duration for running 66 unit tests. The recorded images are not very large, ranging from 81KB to 255KB.

To Reproduce
Set the precision to any value lower than 1 and modify the tested view so they're not pixel-perfect with the reference images anymore.

Expected behavior
Checking whether or not the snapshots are within the accepted precision should be faster. A 12.7x increase for just 36 images is a whole different order of magnitude.

Environment

  • swift-snapshot-testing version 1.9.0
  • Xcode 13.2.1
  • Swift 5.5
  • iOS 15.2
@fjcaetano
Copy link
Author

I believe the issue is just this for-loop, but I don't have a concrete suggestion for how to fix it. Maybe parallelize it with a multi-threaded queue?

for byte in 0..<byteCount {
if oldBytes[byte] != newerBytes[byte] { differentPixelCount += 1 }
if Float(differentPixelCount) / Float(byteCount) > threshold { return false}
}

@gohanlon
Copy link
Contributor

FYI: There's a promising open PR (#571) that aims to address three issues involving that loop, including its surprisingly long execution time (when compiled without optimizations, as is default for "Debug" builds).

@Stengo
Copy link

Stengo commented Jul 22, 2022

Another option would be to move the image diff analysis from the CPU to the GPU.
The package already includes functions to create diff images (which are part of the failure output), so throwing something like the CIAreaAverage Core Image filter on it would allow for very quick evaluation.

The problem solved by #571 could also be tackled by additionally running CIAreaMaximum to see whether any of the pixels is above a certain threshold.

@ejensen
Copy link
Contributor

ejensen commented Sep 12, 2022

The use of CoreImage filters in #628 improves the speed by 90-97%: going from ~1s to ~2ms per snapshot. This is accomplished using the CILabDeltaE filter, but could also be done with a CIColorAbsoluteDifference to calculate the Euclidean color distance instead of a perceptual color difference.

@tahirmt
Copy link
Contributor

tahirmt commented Oct 8, 2022

@ejensen I'm working on a few tests and the precision makes the tests super slow e.g a test takes 0.5s to complete but with 0.98 precision it takes 6s on the latest version.

Edit: It's faster if I also add a preceptualPrecision of 0.98 with precision

@ejensen
Copy link
Contributor

ejensen commented Oct 22, 2022

@ejensen I'm working on a few tests and the precision makes the tests super slow e.g a test takes 0.5s to complete but with 0.98 precision it takes 6s on the latest version.

Edit: It's faster if I also add a preceptualPrecision of 0.98 with precision

The speedup added in #628 was only enabled when preceptualPrecision < 1. I have added another #664 that introduces a similar speedup when preceptualPrecision == 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants