Scala 最便宜的类型是什么?
我需要使用类型(任何类型)作为隐式中的标记作为类型参数,以将其与另一个隐式区分开来。这很奇怪,但这可能是另一个问题。
由于我可以使用任何类型,因此就内存占用和初始化时间而言,我考虑使用最便宜的类型。在这种情况下,它可能不会对性能产生太大影响,但问题很有趣:哪一种是 Scala 最便宜的类型?
在 Java 中,答案显然是 java.lang.Object。但 Scala 有一些“有趣”的类型:Any
、AnyVal
类型以及可能对其进行优化的底层类型。 Nothing
类型无法实例化,因此被排除在本次比较之外。
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.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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这取决于你的具体问题,但是 Scala 或任何语言中最便宜的构造必须是根本不存在的构造......(至少,在运行时不存在)
请允许我介绍 幻像类型,允许编译器静态执行正确的事情,但在到达 JVM 之前就被抹掉了。
同样,您可以轻松地区分两个不同类型的对象,而无需任何标记字段。这是
case 对象
的一个很好的候选者,并且与模式匹配一起工作得非常好。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.我不确定我是否明白“最便宜的类型”的意思...在 Java 中,就内存而言最便宜的数字类型可以是字节,但从性能角度来看,Java 已针对 int 进行了优化。事实上,许多(或大多数)语言都经过优化以与 int(甚至是数据库引擎)一起使用。 Scala是JVM语言,所以我认为使用int更好。
更新:如果问题是关于“标记/未标记”合适的数据类型,我会使用布尔原语。
没有什么是 Any,它是 Java 中的一种对象,任何对象都比任何原始类型需要更多的内存
。顺便说一句,使用布尔值作为标记是很自然的,它提高了代码的可读性(从而提高了代码的可读性(从而得到其他人的支持和理解)。即使有其他的,更优化的我也不会做过早的优化,会选择boolean。
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.
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.
如果您选择
Any
或AnyVal
,那么您传递的任何原语都将被装箱,因此这可能会被排除。AnyRef
确实是一个不错的选择。如果没有进行任何类型参数化,那么“基元”也是不错的选择——例如
Boolean
或Int
。还有
Null
,这是一个非常有趣的选择,因为它根本不分配任何东西,而且它是一个文字,所以它一定会很快。在不知道你到底用它做什么的情况下,我无法判断这是否是有效的选择。另一个有趣的选项是 java.lang.Integer(使用静态方法 valueOf),因为它保证小值的引用相等(您必须检查文档才能看到精确范围是多少),这意味着不涉及分配。
If you choose
Any
orAnyVal
, 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
orInt
, 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 methodvalueOf
), 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.由于 Scala 运行在 Java 之上,我认为相同的答案也适用于 Scala 世界。 Any 类型的 Scala 对象只是某种类型的 Java 对象。
在 Java 中,我认为像 int、short 或 byte 这样的基本类型会比 Object 便宜,但这些类型可能会在 Scala 中包装/装箱。 (不过对此不是 100% 确定。)
更新
如果由于某种原因它必须是一个对象而不是原始类型,那么 String 可能是最好的,因为字符串被保留在 VM 中。因此,整个应用程序中通常只有一个对象实例。
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 会包装原始类型,而原始类型未实现该方法。所以即。 1024*512 没有被包装,但在 1024.toInt*512 中,1024 被包装。
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.