What is Scala's cheapest type?
I need to use a type (any type) as a marker in an implicit as a type parameter, to distinguish it from another implicit. It's weird, but this may be another question.
Since I can use any type, I was thinking of using the cheapest one, in terms of memory footprint and initialization time. It may not affect performance too much in this case, but the question is interesting: Which one is Scala's cheapest type?
In Java, the answer is obviously java开发者_JAVA百科.lang.Object
. But Scala has a few "interesting" types: Any
, AnyVal
types, and bottom types with possible optimizations around them. The Nothing
type cannot be instantiated, so it is excluded from this comparison.
It depends on your exact problem, but the cheapest construct in Scala - or in any language - has got to be one that doesn't exist at all... (at least, not at runtime)
Allow me to introduce Phantom Types, allowing the compiler to statically do the Right Thing, but erased to nothingness before they hit the JVM.
In a similar vein, you can easily distinguish two differently typed objects without needing any marker fields. This is a good candidate for case object
s, and works really nicely alongside pattern matching.
I'm not sure I get what you mean with "cheapest type"... In Java cheapest numerical type in terms of memory can be byte, but from performance POV Java is optimized to work with int. In fact many (or most) languages are optimized to work with int (even DB engines). Scala is JVM language, so I would say that better to use int.
UPDATE: if the question is about "marked / not marked" suitable data type, I would use boolean primitive.
if you type boolean in a Scala program, the type you'll actually get is scala.Boolean. Or if you type float, you'll get scala.Float. When you compile your Scala code to Java bytecodes, however, Scala will compile these types to Java's primitive types where possible to get the performance benefits of Java's primitive types.
Nothing is an Any, which is kind of Object in Java, and any Object needs more memory than any primitive type
And btw, using boolean as marker is natural, it improves your code readability (and hence support, understanding by others). Even if there is anything else, more optimized I would not do premature optimization and would choose boolean.
If you choose Any
or AnyVal
, then any primitive you pass will be boxed, so that's probably out.
AnyRef
is a good choice indeed.
If there isn't any type parameterization going on, then the "primitives" are also good choices -- Boolean
or Int
, for instance.
And there's also Null
, which is a very interesting choice because it doesn't allocate anything at all, and it is a literal, so it is bound to be fast. Without knowing what exactly are you doing with it, I can't tell whether that's valid choice.
Another interesting option is java.lang.Integer
(using the static method valueOf
), because it guarantees reference equality for small values (you'd have to check the docs to see what's the precise range), meaning there's no allocation involved.
Since Scala runs on top of Java I would assume that the same answer would work also in the Scala world. a Scala object of type Any is just a Java Object of some sort.
In Java I think a primitive type like int, short or byte would be cheaper than Object, but those types might be wrapped/boxed in Scala. (not 100% sure about that though.)
Update
If for some reason it has to be a object and not a primitive type, String might be the best, since strings are interned in the VM. So there will usually only be one instance of the object throughout the application.
Scala wraps primitive types, when you run method calls of the wrapper, which the primitive type does not implement. So ie. 1024*512 is not wrapped but in 1024.toInt*512 the 1024 is getting wrapped.
精彩评论