我正在翻译 C++ 代码,并且大量使用 typedef。我不能在 Java 中做到这一点,所以我要做的是:
// C++
typedef unsigned int BucketKey;
// Java
public class BucketKey {
public int val;
}
我不是 Java 专家,实际上是这里的新手,我想知道使用 BucketKey 而不是直接使用 int 会有多贵?
顺便提一下,我需要为至少 5 种以上类型执行此操作。
谢谢
它增加了巨大的开销,特别是如果你有数组。我建议编写一个测试程序进行比较。
在 Javaint[100]
中创建一个包含 100 个整数的数组 - 类似于 C/C++,Integer[100]
或者创建一个YourObjectContainingAnIntMember[100]
包含 100 个对 100 个不同对象的引用(指针)的数组。
更不用说BucketKey
对象将具有引用语义,但int
具有像 C++ 中的值语义:
BucketKey x = new BucketKey(100);
BucketKey y = x
y.value = 200; // x will change as well
int x = 100;
int y = x;
y = 200; // x will remain 100
还值得补充的是,C++ 中的 typedef 也不会创建新类型。所以BucketKey
变量的类型只是整数——但是Java没有typedef可以调用int
更多的方法。具有不同类型的 C++ 解决方案将是
struct BucketKey {
value x;
}
请注意,您的问题与装箱无关:javaint
是原始类型,其装箱版本是java.lang.Integer
. 您在质疑访问类成员是否比访问原始变量慢。大多数 Java 性能问题基本上没有答案:存在差异,但这种差异取决于许多因素,包括:
但是,除非您进行高频交易,否则如果您正确地构建程序以尊重封装,那么与生产力的巨大提高相比,性能影响将是完全可以接受的不利因素。
如果你真的有这样的性能问题并且你考虑在 JVM 上工作,你应该寻找比 Java 更现代的编程语言。
事实上,JVM 不支持 Value 类。然而,Scala 有:
http://docs.scala-lang.org/overviews/core/value-classes.html
如果可能,请使用原始 int 。装箱/拆箱的惩罚并不高,但您应该确定这一点。在任何情况下,您的示例中看起来都不是装箱/拆箱。您正在做出原始与对象的决定。
无论如何,除非您正在制作实时系统或类似的东西,否则您不必为此担心太多。
我同意彼得劳里的观点。使用视觉 vm 来识别瓶颈。我也为此写了一个简短的教程[来源]。
它产生的差异取决于您使用它的程度。如果您每秒使用一百万次。它不会有太大的不同。如果您每秒使用 1000 万次,您会注意到它,如果您每秒使用 1 亿次,则原语会快很多倍。
您应该编写一个简单、清晰的工作程序,然后才对其进行分析(例如使用 VisualVM)以找到瓶颈。您的瓶颈很可能出现在您无法预料的地方。
使用拳击课程有合法要求。
例如,在参数中使用框而不是原语允许 JAX-B 在参数为空时避免在 XML 元素中包含属性。那是为了防止
<employee name='Henry' id=null years=null />
但应该是
<employee name='Henry' />
因此,如果出现这样的需求,不妨使用盒装实例。
我在 Java 编译器方面没有专业知识,但我希望编译器已经完成了优化。我的心理实验似乎表明这将是一种预期且相对简单的优化。
我的想法是,只要 Java 编译器无论如何都会优化装箱,那么在某些时候,您无论如何都需要尝试实例化装箱的实例。为什么不早点去享受它的所有功能和设施呢?
有一点架空装箱和拆箱值。话虽如此,与“典型”程序中的其余处理相比,开销通常可以忽略不计。
我建议使用最坏情况(就密钥访问次数而言)用例构建测试,如果您认为拥有灵活的密钥类型有一些价值,则以两种方式衡量性能。
如果您实际上不需要灵活地更改密钥类型,只需使用int即可。