Java 赋值和条件测试之间的性能差异
这个问题专门针对Java语言,但如果是这样的话,我不介意反馈这是一个一般概念。我想知道哪个操作可能更快,或者在为变量赋值和对值执行测试之间是否没有区别。对于这个问题,我们可以有一系列的布尔值,这些值将有许多更改请求。我想知道,与每次请求期间简单更改值的速度相比,是否需要更改值的测试会被视为浪费Java 赋值和条件测试之间的性能差异,java,Java,这个问题专门针对Java语言,但如果是这样的话,我不介意反馈这是一个一般概念。我想知道哪个操作可能更快,或者在为变量赋值和对值执行测试之间是否没有区别。对于这个问题,我们可以有一系列的布尔值,这些值将有许多更改请求。我想知道,与每次请求期间简单更改值的速度相比,是否需要更改值的测试会被视为浪费 public static void main(String[] args){ Boolean array[] = new Boolean[veryLargeValue]; for(int
public static void main(String[] args){
Boolean array[] = new Boolean[veryLargeValue];
for(int i = 0; i < array.length; i++) {
array[i] = randomTrueFalseAssignment;
}
for(int i = 400; i < array.length - 400; i++) {
testAndChange(array, i);
}
for(int i = 400; i < array.length - 400; i++) {
justChange(array, i);
}
}
这可能是justChange方法
public static void testAndChange(Boolean[] pArray, int ind) {
if(pArray)
pArray[ind] = false;
}
public static void justChange(Boolean[] pArray, int ind) {
pArray[ind] = false;
}
如果我们最终遇到一个非常罕见的情况,即提供给方法的范围内的每个值都是假的,那么会有一种方法最终变得比另一种方法慢的情况吗?是否有针对类似问题的最佳实践
编辑:我想添加这个来帮助进一步澄清这个问题。我意识到,当可以利用更大或更高效的数据类型时,可以将数据类型分解为答案。我更专注于任务本身。测试任务“如果(条件测试)”比赋值任务“x=avalue”慢、快或不确定,没有额外的信息(如数据类型)。正如@Tripkinetics指出的,这两种方法在语义上存在差异。由于使用的是
Boolean
而不是Boolean
,因此其中一个值可能是null
引用。在这种情况下,第一个方法(使用if
-语句)将抛出异常,而第二个方法只是将值分配给数组中的所有元素
假设您使用boolean[]
而不是boolean[]
。优化是一个不可判定的问题。在极少数情况下,添加if
-语句可以获得更好的性能。例如,大多数处理器使用缓存,而if
-语句可能导致执行的代码恰好存储在两个缓存页上,而没有if
的缓存页则会导致缓存故障。也许您认为可以保存赋值指令,但代价是获取指令和条件指令(这会破坏CPU管道)。赋值与获取值的成本大致相同
但是,一般来说,可以假设添加if
语句是无用的,并且几乎总是会导致代码变慢。因此,您可以非常安全地声明,if
语句将始终降低代码的速度
更具体地说,有更快的方法将范围设置为false。例如,使用位向量,如:
long[] data = new long[(veryLargeValue+0x3f)>>0x06];//a long has 64 bits
//assign random values
int low = 400>>0x06;
int high = (veryLargeValue-400)>>0x06;
data[low] &= 0xffffffffffffffff<<(0x3f-(400&0x3f));
for(int i = low+0x01; i < high; i++) {
data[i] = 0x00;
}
data[high] &= 0xffffffffffffffff>>(veryLargeValue-400)&0x3f));
long[]data=new long[(veryLargeValue+0x3f)>>0x06]//一个长字符有64位
//分配随机值
int low=400>>0x06;
int高=(veryLargeValue-400)>>0x06;
数据[低]&=0xFFFFFFFFFFFF(veryLargeValue-400)和0x3f);
其优点是处理器可以一次对32位或64位执行操作。由于布尔值是一位,通过将位存储到
long
或int
中,操作是并行进行的。如何将false
设置为pArray
?请记住,Java是一种传递值语言,没有C中的指针。虽然这是一个有效的问题,我没有数据来回答,请记住“过早优化是万恶之源”这句话。编写清晰且可维护的代码比编写速度快得多的代码要快得多。您的代码似乎是错误的:不能将false设置为数组。你不能调用一个不带参数的方法。。。请提供原始源代码-否则,任何帮助您的尝试都注定会失败。如果您关心性能,请不要使用大小为1/4的布尔[]
或大小为1/32的位集?这将比测试值产生更大的差异。顺便说一句,丢失的分支可能比分配昂贵100倍。这就是BitSet.clear(400,veryLargeValue-400)
为您所做的。;)但是Boolean
s是对象,而且Boolean
的大小不是未定义的吗?请注意这种情况。@Tripkinetics:aBoolean
确实是一个对象,因此存在第三种状态:null
。这将导致每个布尔值为32位(用于参考,有些用于对象本身)。我认为问题更具体到boolean[]
@PeterLawrey:没错,但其中一些数据结构的问题是,它们不能解释为什么工作得更快。例如,我的一些同学对HashMap的工作原理一无所知。这对于理解某些代码(不)缩放的原因至关重要。@CommuSoft如果您理解了CS 101-哈希表的工作原理
,那么您就知道了关于HashMap需要知道的大部分内容。我知道Java试图将开发人员与细节隔离开来,但我也认为您应该期望专业开发人员了解基础知识。