2011-02-05 55 views
8

我需要使用一个类型(任何类型)作为一个标记在一个隐式的类型参数,以区别于另一个隐式。这很奇怪,但这可能是另一个问题。斯卡拉最便宜的类型是什么?

因为我可以使用任何类型的,我想用最便宜的之一,在内存占用初始化时间的条款。在这种情况下,它可能不会影响性能,但问题很有趣:哪一个是Scala最便宜的类型?

在Java中,答案显然是java.lang.Object。但斯卡拉有一些“有趣”的类型:Any,AnyVal类型和底部类型可能优化他们周围。 Nothing类型不能被实例化,所以它被排除在这个比较之外。

+3

有趣的是,我会说在java中最便宜的类型是一个简单的int。 – Yahel 2011-02-05 08:08:00

+0

我不知道这是多么“便宜”,但没有什么可用:`def x(_:Nothing)=(); x(null.asInstanceOf [Nothing])`只是*不*尝试使用Nothing :-) – 2011-02-05 08:21:27

+0

在“根”问题上看到一个问题也很有趣。 – 2011-02-05 08:24:53

回答

3

如果您选择AnyAnyVal,那么您传递的任何基元都将被装箱,因此可能已经过期。

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

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

还有Null,这是一个非常有趣的选择,因为它根本不分配任何东西,而且它是一个文字,所以它必然是快速的。不知道你到底在干什么,我不知道这是否是有效的选择。

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

1

既然Scala运行在Java之上,我会假设同样的答案也适用于Scala世界。 Any类型的Scala对象只是某种Java对象。

在Java中,我认为像int,short或byte这样的原始类型比Object更便宜,但这些类型可能会被包装/装箱在Scala中。 (不是100%地肯定,虽然。)

更新

如果由于某种原因,它必须是一个对象,而不是原始类型,字符串可能是最好的,因为字符串在虚拟机实习。所以在整个应用程序中通常只有一个对象实例。

4

我不知道我得到你的意思“最廉价型” ......在Java中的内存方面最廉价的数值类型可以是字节什么,但是从性能POV Java的优化与诠释工作。事实上,很多(或大多数)语言都经过优化,可以与int(甚至是DB引擎)一起工作。 Scala是JVM语言,所以我会说最好使用int。

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

如果您在斯卡拉 程序boolean类型,你实际上会得到 类型是scala.Boolean。或者如果你输入 浮点数,你会得到scala.Float。当您将您的Scala代码编译为Java 字节码时,Scala会将这些类型编译为 这些类型为Java的原始类型 ,在可能的情况下获得Java基本类型的性能 。

没有什么是任何,这是一种在Java对象,任何对象需要更多的内存比任何基本类型

而且顺便说一句,使用布尔作为标记是很自然的,它提高了代码的可读性(和因此支持,他人的理解)。即使有其他的东西,更优化我不会做过早的优化,并会选择布尔值。

13

这取决于你确切的问题,但是在Scala中最便宜的构造 - 或者任何语言 - 都必须是一个根本不存在的构造......(至少,不是在运行时)

允许我引入Phantom Types,允许编译器静态地执行正确的操作,但在它们到达JVM之前被清除为空。

以类似的方式,您可以轻松地区分两个不同类型的对象而不需要任何标记字段。这是case object的好选择,并且与模式匹配一​​起工作得非常好。

0

当您运行包装程序的方法调用时,Scala会封装基本类型,而原始类型不会实现。所以即, 1024 * 512未被包装,但在1024.toInt * 512中,1024被包装。