JuliaImages / JuliaImages/ImageFiltering.jl
imfilter! is slower with an Array source than an OffsetArray
Nobody has claimed this yet.
- Dominant language
- Julia
- Stars
- 104
- Forks
- 52
- PR merge metrics
- No merged PRs in 30d
Description
Could imfilter use the secret sauce from the specialization for OffsetArray in more cases? I've not wrapped my head fully around all the indexing permutations, but here's a simple benchmark test case:
This hits the fast OffsetArray implementation:
img = rand(0:1, 1024, 1024)
const kern = ImageFiltering.factorkernel(centered([10 2 10; 2 1 2; 10 2 10]))
src = ImageFiltering.padarray(Int, img, Pad(:reflect, 1,1))
dest = similar(img)
@benchmark imfilter!($dest, $src, kern, ImageFiltering.NoPad())
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 11.882 ms (0.00% GC)
median time: 11.904 ms (0.00% GC)
mean time: 11.910 ms (0.00% GC)
maximum time: 13.976 ms (0.00% GC)
--------------
samples: 420
evals/sample: 1
Theoretically, I think this could be faster as it does fewer computations than the one above (it skips the outside edge, yes?), but it falls back to the generic implementation:
src = img
dest = OffsetArray(similar(img, size(img).-2), (1, 1))
@benchmark imfilter!($dest, $src, kern, ImageFiltering.NoPad())
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 19.408 ms (0.00% GC)
median time: 19.470 ms (0.00% GC)
mean time: 19.501 ms (0.00% GC)
maximum time: 21.914 ms (0.00% GC)
--------------
samples: 257
evals/sample: 1
This restores a bit of performance and hits the specialized method, but it's still a bit slower:
src = OffsetArray(img, (0,0))
dest = OffsetArray(similar(img, size(img).-2), (1, 1))
@benchmark imfilter!($dest, $src, kern, ImageFiltering.NoPad())
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 13.947 ms (0.00% GC)
median time: 13.965 ms (0.00% GC)
mean time: 13.985 ms (0.00% GC)
maximum time: 18.823 ms (0.00% GC)
--------------
samples: 358
evals/sample: 1
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read the specialized and generic implementations in src/imfilter.jl around lines 997 and 1012. Reproduce the three Julia benchmark cases from the issue, then trace the indexing permutations that determine method selection. Done means the Array-source case uses an appropriate fast path without changing imfilter! results, with the benchmark showing the expected improvement.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- julia
- Domain
- computer-vision, performance
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100