Hi everyone,
I have encountered a pretty annoying performance bottleneck when using StatsBase.Weights
, which is a mutable struct (whatever may be the reason for that :P) , in a multithreaded setting.
After going down the rabbit hole, I have seen that the issue is that allocations seem to explode whenever using a mutable struct in a multithreaded setting. For example:
mutable struct teststr
i::Int
end
function test()
for _ in 1:8000
Threads.@threads for i in 1:100 # removing @threads will result in stable allocations
a = @allocated teststr(i)
if a > 32*200
error("Allocation of $(Base.format_bytes(a))")
end
end
end
end
test()
shows that in some cases, julia takes over 10 kilobytes for a single allocation .
Is this somehow expected behaviour or a bug? I can imagine that @allocated
somehow also counts allocations from the multithreading, but the vscode profiler also shows a lot of time being spent in constructing teststr
(or, rather StatsBase.Weights
in my original use case).
Otherwise, what is the best way to resolve my concrete issue? Is there some immutable version of StatsBase.Weights
? Should I pre-allocate it and update the struct with the appropriate weights each time? This will probably work but it feels rather hacky and overcomplicated to me, as it should be only a simple wrapper type…