在性能和有效内存使用方面,以下哪个更好?
Boolean isItTrue(arg){
return Boolean.TRUE;
}
boolean isItTrue(arg){
return Boolean.TRUE
}
Boolean isItTrue(arg){
return true;
}
boolean isItTrue(arg){
return true;
}
使用基本类型应该更快更容易,但另一方面,当使用对静态对象的引用时,不会创建新值。或者它在编译器级别上进行了优化,所有true
和false
都被对静态对象的引用所取代,以节省内存?
首先,使用任何一个的性能优势都是很可能太小而不相关。代码的简单性/可读性/可维护性更为重要……在绝大多数情况下。
所有示例都不涉及创建Boolean
实例。
从理论上讲,4个中的3个可能触发Boolean
类和的初始化,否则您的应用程序不会这样做。在这个极不可能发生的事件中,您的整个应用程序将分配2个本来不会分配的对象。初始化可能需要几微秒,并且长期消耗几个字节的RAM(少于50)。
这个将等于或比其他的更快,因为它只需要将寄存器设置为0。
boolean isItTrue(arg){
return true;
}
单独来看,
必须从内存中加载一个静态引用,而不是从寄存器中取零。但是,在某些情况下,JIT编译器可以将其优化掉。
Boolean isItTrue(arg){
return Boolean.TRUE;
}
从表面上看,这涉及到对Boolean.valueOf(true)
的调用"box"true
,但JIT编译器应该能够通过内联调用将其优化为与前一个相同的代码。
Boolean isItTrue(arg){
return true;
}
从表面上看,这涉及到调用Boolean.booleanValue(Boolean.TRUE)
来"unbox";Boolean
。这个调用可以内联。JIT编译器也可以避免加载Boolean
对象的引用并获取其value字段。
boolean isItTrue(arg){
return Boolean.TRUE
}
底线是,这4种选择的相对性能取决于JIT编译器在优化方面的成功程度。这将取决于上下文、JIT编译器的具体情况、JVM设置等等。在最好的情况下,JIT编译器可以(至少在理论上)为它们生成相同的(最优的)代码。
如果有任何性能增益,它是如此微小以至于无关紧要。布尔。TRUE和布尔值。FALSE在任何情况下都不会返回一个新对象。
比起这种微优化,更有利于代码维护人员的清晰度。问题不应该是"哪个更小/更快",而应该首先表达你的意思。
如果该方法返回一个布尔对象,那么接收该方法的人需要判断它是否有可能为null,如果为为null,则它可能意味着与真/假不同的东西,如"我们不知道"。
返回布尔类型,如果这是你的意思,否则,如果你想允许Null,那么布尔。
如果返回布尔值,则
return true; // or false
必须比依赖自动装箱更好,同样是为了清晰和性能。
如果返回布尔值,则
return Boolean.TRUE
必须是好的,它只是避免产生额外的垃圾,就像我反对微优化一样,我认为故意降低效率没有价值。我认为,它也更清晰,因为你明显匹配返回类型。
它们会快得多。我认为这两者之间不会有任何区别。
Boolean isItTrue(arg){
return Boolean.TRUE;
}
boolean isItTrue(arg){
return true;
}
但是其他的实现将会慢一些,因为它将在后端装箱和拆箱,这将花费一些处理器的时间。
编辑
我通过实施4种不同的方法收集了一些事实。我只是想和你分享,我不知道这是不是写作的方式。
Boolean isItTrue(){
return Boolean.TRUE;
}
Free Memory before start --> 16030936
Time taken in Secs --> 7.844
Free Memory After Process --> 15940472
Memory Usage --> 90464
boolean isItTrue(){
return Boolean.TRUE;
}
Free Memory before start --> 16030936
Time taken in Secs --> 10.109
Free Memory After Process --> 15940472
Memory Usage --> 90464
Boolean isItTrue(){
return true;
}
Free Memory before start --> 16030936
Time taken in Secs --> 7.906
Free Memory After Process --> 15940472
Memory Usage --> 90464
boolean isItTrue(){
return true;
}
Free Memory before start --> 16030936
Time taken in Secs --> 7.828
Free Memory After Process --> 15940472
Memory Usage --> 90464
主类
public static void main(String[] args){
NewClass n = new NewClass();
long sysTime = System.currentTimeMillis();
Runtime rt = Runtime.getRuntime();
long freeMem = rt.freeMemory();
System.out.println( "Free Memory before start --> " + freeMem );
for( int i = 0; i < Integer.MAX_VALUE; i++ ){
n.isItTrue();
}
System.out.println( "Time taken in Secs --> " + (System.currentTimeMillis() - sysTime)/1000D);
System.out.println( "Free Memory After Process --> " + rt.freeMemory() );
System.out.println( "Memory Usage --> " + ( freeMem - rt.freeMemory() ) );
}
最后一个
boolean isItTrue(arg){
return true;
}
我使用Boolean
只有当方法有时需要返回null
我的经验法则如下:
- 默认选择基本类型(
boolean
)。 - 如果我需要空性或需要在容器中存储值,我使用类(
Boolean
)。
boolean isItTrue(arg){
return true;
}
就性能而言,唯一可以肯定的是,很难想象使用Boolean
会比使用boolean
快。它是否会变慢或相同取决于很多事情,一般来说是不可能回答的。
如果你真的关心这个,在重要的地方剖析代码!
根据这种逻辑,对静态对象本身的引用的开销与真值一样高,甚至更高。
使用对象可能比原语慢一些,但我不担心:差异是无关紧要的。
使用最后一个(仅boolean
)。即使编译器将它们都优化为相同的东西,至少您使编译器的工作更容易(您知道这不是一件容易的工作!)。
加上更少的按键(不需要按shift)。但实际上,使用包装器类的唯一原因是需要将其设置为null
,并用于LinkedList<E>
等通用数据结构。
java.lang。布尔值占用16字节
如果你只是在寻找性能和内存大小的问题,这是一种方法:
boolean isItTrue(arg){
return true;
}