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