I wrote a function which computes something using a SortedSet
of a type I defined, which is a fixed-size SVector
with no variable-size fields. I thought that maybe using a Set
would make it faster, so I changed SortedSet
to Set
and ran the function. It threw a MethodError
trying to call decompose
on my type. The stacktrace indicates that decompose
is called from hash
. How should I define decompose
on my type, or should I define hash
?
decompose
is an implementation detail internal to Base
. Define equality and hashing for your type.
I believe you’d only hit this if your type subsets Number
(or some subtype thereof). Note that it can be tricky to extend numeric types — you can often find yourself deep in internals like these pretty quickly.
Also, equality and hashing must be consistent. In particular this holds even when comparing values of two different types. This basically means that hash
for custom Number
types needs to be implemented by converting to a Number
type defined by Base
(or Core
), and then hashing that. E.g., if YourType(7) == 7
, then hash(YourType(7), h) === hash(7, h)
must hold too, for any h::UInt
.
It is a subtype of Real, and can be multiplied and divided, but it’s not exported, ==
is not defined between this type and anything else, and it’s never used in a Union
. So I defined a hash with no relation to the hash of floats and integers, and the algorithm runs three times as fast as it did with SortedSet
.