我有一个嵌套循环,它迭代数组中两个元素的所有组合。但是,如果两个值之和太大,我想跳到下一个x
。
这是Java代码片段:
/* Let array be an array of integers
* and size be equal to its length.
*/
for (int a = 0; a < size; a++)
{
int x = array[a];
for (int b = 0; b < size(); b++)
{
int y = array[b];
if ((x + y) < MAX)
{
// do stuff with x and y
}
else
{
// x + y is too big; skip to next x
break;
}
}
}
这完全符合预期。
但是,如果我将break
语句替换为b = size;
,则会令人惊讶地大约快20%。请注意,通过设置b = size;
,内部{ {1}}条件变为false,执行继续到外for
循环的下一次迭代。
为什么会这样?似乎a
应该更快,因为我认为它会保存一个赋值,跳转和比较。虽然显然没有。
答案 0 :(得分:2)
IMO,最可能的解释是某种JVM预热效果,特别是因为整体时间(120ms对74ms)非常小。如果你将那个循环包裹在另一个循环中,这样你就可以在同一次运行中重复执行时间测量,这个异常很可能会消失。为什么会这样?似乎休息应该更快......
(只是增加数组大小并不一定会有所帮助。确保你已经考虑到JVM预热异常的最佳方法是使用基准测试框架;例如Caliper。但是,失败将#34;片段&#34;放入方法并重复调用。)
...因为我认为它可以保存任务,跳转和比较。虽然显然没有。
根本不清楚。您的Java代码由javac
(或您的IDE)编译为字节码。当你运行代码时,它开始解释字节码,然后在一点之后它们被JIT编译器编译成本机代码:
JIT编译花费时间(可能)包含在您的时间测量中......以及一个预热异常来源。
JIT编译器生成的代码受到解释时收集的统计信息的影响。通常测量的一个问题是分支(例如if
测试)是否采用这种方式。这用于进行分支预测......如果正确的话,可以使测试和分支指令序列更快。