Hi all,
I am playing with channels and I have this example code.
# Example producer, will generate `N` element using function
# `ϕ` and push them in a channel of size `csize`
function Produce(ϕ, x₀::T, N::Int, csize::Int=20) where T
# create closure to feed the channel with
function f(ch::Channel)
# preallocate a set of elements to be reused by `ϕ`
xs = T[similar(x₀) for _ = 1:csize]
# put elements in channel, will block as soon as `i == csize`
for i = 1:N
put!(ch, ϕ(xs[i % csize + 1]))
end
close(ch)
end
return Channel(f; ctype=T, csize=csize)
end
# Example consumer function. Just sum the sums of the
# stream elements.
function Consume(stream::Channel{T}) where T
s = sum(take!(stream))
while isopen(stream) || isready(stream)
s += sum(take!(stream))
end
s
end
# example function that modifies x in place
ϕ(x) = (x .= 2.*x .+ 1; return x)
# warm up
stream = Produce(ϕ, randn(1000), 1000, 10)
Consume(stream)
# Time function for increasing number of generated
# elements and fixed channel size = 10
# Number of allocations grows
for N = [10, 100, 1000, 10000]
stream = Produce(ϕ, randn(1000), N, 10)
@time Consume(stream)
end
println()
# Time function for increasing channel size
# Number of allocations decreases
for csize = [10, 100, 1000, 10000]
stream = Produce(ϕ, randn(1000), 10000, csize)
@time Consume(stream)
end
This produces the output
0.000004 seconds (1 allocation: 16 bytes)
0.000077 seconds (27 allocations: 896 bytes)
0.000670 seconds (207 allocations: 3.688 KiB)
0.006473 seconds (2.01 k allocations: 31.813 KiB)
0.007672 seconds (2.01 k allocations: 31.813 KiB)
0.006934 seconds (208 allocations: 9.484 KiB)
0.009498 seconds (27 allocations: 16.609 KiB)
0.005006 seconds (1 allocation: 16 bytes)
What I don’t get is the largish number of allocations done in the second set of calls when the channel
size is small compared to the number of elements produced N
. Any suggestions?
Thanks!