Scala 最便宜的类型是什么?

发布于 2024-10-15 21:37:46 字数 353 浏览 2 评论 0原文

我需要使用类型(任何类型)作为隐式中的标记作为类型参数,以将其与另一个隐式区分开来。这很奇怪,但这可能是另一个问题。

由于我可以使用任何类型,因此就内存占用初始化时间而言,我考虑使用最便宜的类型。在这种情况下,它可能不会对性能产生太大影响,但问题很有趣:哪一种是 Scala 最便宜的类型?

在 Java 中,答案显然是 java.lang.Object。但 Scala 有一些“有趣”的类型:AnyAnyVal 类型以及可能对其进行优化的底层类型。 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

成熟稳重的好男人 2024-10-22 21:37:46

这取决于你的具体问题,但是 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 objects, and works really nicely alongside pattern matching.

梦断已成空 2024-10-22 21:37:46

我不确定我是否明白“最便宜的类型”的意思...在 Java 中,就内存而言最便宜的数字类型可以是字节,但从性能角度来看,Java 已针对 int 进行了优化。事实上,许多(或大多数)语言都经过优化以与 int(甚至是数据库引擎)一起使用。 Scala是JVM语言,所以我认为使用int更好。

更新:如果问题是关于“标记/未标记”合适的数据类型,我会使用布尔原语。

如果您在 Scala 中输入布尔值
程序,你实际得到的类型
是 scala.Boolean。或者如果您输入
float,你会得到scala.Float。什么时候
将 Scala 代码编译为 Java
但是,Scala 会编译字节码
这些类型转换为 Java 的原始类型
尽可能获得性能
Java 原始类型的优点。

没有什么是 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.

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.

山色无中 2024-10-22 21:37:46

如果您选择 AnyAnyVal,那么您传递的任何原语都将被装箱,因此这可能会被排除。

AnyRef 确实是一个不错的选择。

如果没有进行任何类型参数化,那么“基元”也是不错的选择——例如 BooleanInt

还有 Null,这是一个非常有趣的选择,因为它根本不分配任何东西,而且它是一个文字,所以它一定会很快。在不知道你到底用它做什么的情况下,我无法判断这是否是有效的选择。

另一个有趣的选项是 java.lang.Integer(使用静态方法 valueOf),因为它保证小值的引用相等(您必须检查文档才能看到精确范围是多少),这意味着不涉及分配。

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.

暗藏城府 2024-10-22 21:37:46

由于 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.

阳光①夏 2024-10-22 21:37:46

当您运行包装器的方法调用时,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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文