I've noticed that, while ListConvolve
is very fast, it becomes much slower when you use anything but the standard Times,Plus
as your functions (cf. ListConvolve documentation to see this in action; it looks like ListConvolve[ker,list,klist,padding,g,h]
).
As an example, I predefine a 500x500 array and call it array500
. I then define two functions, LC
and LC2
, as follows:
LC[ar_] :=
ar ListConvolve[-{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, ar, {2, -2}, 0,
Times, Plus];
LC2[ar_] :=
ar ListConvolve[-{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, ar, {2, -2}, 0,
Times, List];
(n.b. that the LC[ar] is also == ar ListConvolve[-{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, ar, {2, -2}, 0];
, the default)
When I run LC
on array500
, it's understandably very speedy: RepeatedTiming@LC@array500
returns a mere .16s. However, RepeatedTiming@LC2@array500
takes significantly longer at .974s. It's a 61x slowdown! I'm confused as to why it's so different, especially because it never even has to add the elements together. If I change the option from List
to Times
, it still takes about the same (long) time.
Is anybody able to clarify why this huge speed difference exists, and whether there's any way to work around it?
EDIT: I realized that I'm doing n
products for an n x n
array with LC
and 9n
with LC2
due to my multiplication out front by ar
, but this doesn't seem to matter much (as I expected it wouldn't, but I wanted to check!)—removing this, there's still ~60-70x slowdown by using Times,List
over Times,Plus
.
ListConvolve
andListCorrelate
could be used in some creative ways if the generalised versions were anywhere near as fast as the default but its never been the case unfortunately. $\endgroup$