[英]Garbage Collection of Looping statements in Java
如今,我参加了Codegolf的一些比赛。 对于特定问题。 我已经在Java中提交了一个答案,其中包含这样的嵌套循环。
for(int i=0; i < 20_00_00_000; i++){
for(int j=0; j < 10_00_000; j++){
//declare some variables
//do operations
//modify variables outside of for loop
}
}
假设这需要n
次时间。
另一位成员发表了类似的答案,但像这样。
for(int i=0; i < 20_00_00_000; i++){
nextLoop(pass necessary args);
}
private void nextLoop(necessary args){
for(int j=0; j < 10_00_000; j++){
//declare some variables
//do operations
//modify variables outside of for loop
}
}
但这仅需要n
次的60%。 然后我意识到这将与嵌套循环的Garbase集合有关。 两种代码的逻辑相同,但是将内部循环分成一种方法可以使其更快。 我认为这是因为nextLoop()
方法完成后会发生垃圾回收,但是垃圾回收中存在与First代码嵌套的for循环有关的问题。
现在关于第一个代码,一旦父循环的下一次迭代开始,内部for循环占用的内存是否不会自动垃圾回收?
方法2(更快)
public class MinPrimeFactorSum {
static int[] primes = new int[20_000_000];
static int count = 0;
static int temp;
static int p;
static long total = 2;
public static void main(String[] args) {
long start = System.nanoTime();
int i=3;
for(; i<1_00_00_000; i += 2) {
// Calling the inner loop as a method
temp = getData(i);
if( i == temp ) {
primes[count] = temp;
count++;
}
total += temp + 2;
}
System.out.println( --i + ": " + total + " in " + (System.nanoTime() - start)/1000000 + " milliseconds" );
}
// Inner Loop as a method
private static int getData(int i) {
temp = i;
for(int index = 0;index < count; index++ ) {
p = primes[index];
if( i % p == 0 ) {
temp = p;
break;
}
if( p > Math.sqrt(i) ) {
break;
}
}
return temp;
}
}
方法1(较慢)
public class MinPrimeFactorSum {
static int[] primes = new int[20_000_000];
static int count = 0;
static int temp;
static int p;
static long total = 2;
public static void main(String[] args) {
long start = System.nanoTime();
int i=3;
for(; i<1_00_00_000; i += 2) {
temp = i;
// Inner Loop Starts
for(int index = 0;index < count; index++ ) {
p = primes[index];
if( i % p == 0 ) {
temp = p;
break;
}
if( p > Math.sqrt(i) ) {
break;
}
}
// Inner Loop ends
if( i == temp ) {
primes[count] = temp;
count++;
}
total += temp + 2;
}
System.out.println( --i + ": " + total + " in " + (System.nanoTime() - start)/1000000 + " milliseconds" );
}
}
经过一系列测试后,我才发布了这个问题。
较慢的代码使用静态温度,而较快的代码在函数内部声明一个本地温度。
要使两者相等,请尝试替换行temp = i;
到int temp = i;
然后再次测量。
编辑:我注意到您的评论,您已经使它们都使用了静态温度,并且调用该方法的版本仍然更快。 我认为差异是由于JIT造成的:它可能比优化内联版本更早地优化了方法(然后内联了)。 同样,您的基准测试方法也太简单了。 对Java代码进行基准测试非常棘手。 例如,请参阅Robust Java Benchmarking(IBM技术库)以获得对该主题的良好处理。
顺便说一下,在我的情况下,两种情况之间的时序差异仅为0.5%(3585 vs 3595 ms)。 当我优化您的代码时(通过将对Math.sqrt的调用移到循环外),它的运行速度快一倍以上,并且区别更加明显(1577与1687)。 (这是在32位Windows Core 2 Quad Q8200上。)
是的,不会在第二个循环的第一个循环内存中进行垃圾回收。 未被收集的原因是依赖关系,第一个循环中的第二个循环对第一个循环具有依赖性。因此,第二个循环中的事物取决于第一个循环中的事物,它们彼此之间是不完整的,但在第二种情况下,两个循环是独立的,一个循环不依赖于第二个循环,这就是为什么要进行垃圾回收的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.