I was experimenting with the sort function where I gave to the by keyword a type related to each element of the array, but types can’t be compared with each others. So I tried to convert the type to a symbol, but it was very slow so I tried to benchmark the conversion and I got
Symbol(x) for generic x falls back to printing x to a string, then converting the string to a symbol. This is going to be slow (allocating a new string on each call, among other things).
If you just want an arbitrary ordering, you can compare by the objectid of the type. For example:
Of course, if you have a mixed-type container, such as an array holding elements of different types, you are inherently looking at sub-par Julia performance to start with.
One the one hand, it’s pretty painless to add optimized methods to Base, and of course internal methods can depend on internal implementation details.
On the other hand, converting types to symbols is ordinarily something that would only occur during metaprogramming, in which context performance is usually not so much of a concern. If it is performance-sensitive for you, this might be an indication that you should re-think how you are using Julia — the cornerstone of making Julia fast is to make sure that types are inferred at compile-time in critical code, and it seems like you are violating that maxim.
Why would you convert to symbol for sorting. In my understanding, a symbol is an just opaque name and should merely be compared for equality. Was surprised that an ordering relation is defined on symbols at all, but it probably makes sense as nameof returns a symbol (which arguably is not its name).
In any case, if you want to order types by name, just use nameof – which by the way uses t.name.name on data types internally already.
Notice that Symbol(x), because it falls back to print and therefore show, uses abbreviated aliases like ComplexF64, which may not be what you want for sorting. To omit the type aliases, you need to call show directly with :compact=>false in the IOContext:
i.e. if you wanted to sort by the full type names, you could use by=x -> sprint(show, typeof(x); context=:compact=>false).
Of course, since this involves allocating a string for every element to be sorted (same as Symbol(T) under the hood), it won’t be blazingly fast. But, as I commented above, if you need sorting by type name to be blazingly fast then you might want to re-think your whole approach.
yes, I know that heterogeneous containers are not very performant and indeed I think that the current approach is not perfect because it is too type unstable but I thought that this conversion could have been useful in some other context, but I agree that it could be used in metaprogramming for the most part where performance is not very important, nonetheless if it possible to have an optimized version even for parametric types than I would consider improving the current Base method, though it’s maybe impossible to keep the current behaviour if Symbol(Complex{Float64}) returns an alias