-
-
Notifications
You must be signed in to change notification settings - Fork 16
Closed
Description
I was very pleased to discover that this is a thing that's been carved out from Flux, but was slightly surprised by the following performance:
using Functors, BenchmarkTools
using Functors: functor
struct Bar{T}
x::T
end
@functor Bar
bar = Bar(5.0)
julia> @benchmark fmap(Float32, bar)
BenchmarkTools.Trial:
memory estimate: 608 bytes
allocs estimate: 16
--------------
minimum time: 952.304 ns (0.00% GC)
median time: 984.652 ns (0.00% GC)
mean time: 1.040 μs (1.92% GC)
maximum time: 76.549 μs (96.27% GC)
--------------
samples: 10000
evals/sample: 23
Digging down a little, functor
seems to be performant:
julia> @benchmark functor($bar)
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 1.455 ns (0.00% GC)
median time: 1.470 ns (0.00% GC)
mean time: 1.589 ns (0.00% GC)
maximum time: 39.906 ns (0.00% GC)
--------------
samples: 10000
evals/sample: 1000
👍
Similarly, isleaf
seems to be fine:
using Functors: isleaf
julia> @benchmark isleaf($bar)
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 0.020 ns (0.00% GC)
median time: 0.032 ns (0.00% GC)
mean time: 0.030 ns (0.00% GC)
maximum time: 0.050 ns (0.00% GC)
--------------
samples: 10000
evals/sample: 1000
👍
So there's something else going on in fmap
and fmap1
that I assume has something to do with the IdDict
that's being used. So, I would be interested to know a) what the need for the cache is (it's kind of un-obvious to me) and b) whether there's a way to get rid of all of this overhead as it seems kind of unnecessary in this simple case?
edit: I realised while out on a walk that it's probably something to do with diamonds in the dependency graph for any particular data structure. Is this the case?
Metadata
Metadata
Assignees
Labels
No labels