考虑以下两个代码示例。所有基准测试都在用于计算采样执行时间平均值的容器之外完成。在我的机器上,运行Windows 7和JDK 1.6,我看到示例2中的平均执行时间比示例1慢近1000倍。我可以推测的唯一解释是编译器正在优化LinkedList使用的一些代码损害其他一切。有人能帮助我理解这个吗?
示例1:使用数组
public class TimingTest
{
static long startNanos, endNanos;
static long[] samples = new long[1000];
public static void main(String[] args)
{
for (int a = 0; a < 100; a++)
{
for (int numRuns = 0; numRuns < 1000; numRuns++)
{
startNanos = System.nanoTime();
long sum = 0;
for (long i = 1; i <= 500000; i++)
{
sum += i % 13;
}
endNanos = System.nanoTime() - startNanos;
samples[numRuns] =(endNanos);
}
long avgPrim = 0L;
for (long sample : samples)
{
avgPrim += sample;
}
System.out.println("Avg: " + (avgPrim / samples.length) );
}
}
}
示例2:使用LinkedList
public class TimingTest
{
static long startNanos, endNanos;
static List<Long> samples = new LinkedList<Long>();
public static void main(String[] args)
{
for (int a = 0; a < 100; a++)
{
for (int numRuns = 0; numRuns < 1000; numRuns++)
{
startNanos = System.nanoTime();
long sum = 0;
int index = 0;
for (long i = 1; i <= 500000; i++)
{
sum += i % 13;
}
endNanos = System.nanoTime() - startNanos;
samples.add(endNanos);
}
long avgPrim = 0L;
for (long sample : samples)
{
avgPrim += sample;
}
System.out.println("Avg: " + (avgPrim / samples.size()));
}
}
}
答案 0 :(得分:3)
这里有些错误:当我运行阵列版本时,我的平均执行时间为20000纳秒。我的2 GHz CPU完全不可能在那段时间内执行500000次循环迭代,因为这意味着平均循环迭代需要20000/500000 = 0.04 ns或0.08 cpu cpu周期......
主要原因是时序逻辑中存在错误:在数组版本中,您执行
int index = 0;
每个时间,因此
samples[index++] =(endNanos);
将始终分配给第一个数组元素,将所有其他元素保留为默认值0.因此,当您获取数组的平均值时,您将获得最后一个样本的1/1000,而不是所有样本的平均值。
实际上,如果将索引声明移到循环之外,则两种变体之间没有报告显着差异。
答案 1 :(得分:0)
这是你的代码的真实运行(为了清晰起见,重命名了类,并且为了时间的推移,将每个循环切换到a < 1
):
$ for f in *.class
do
class=$(echo $f | sed 's`\(.*\)\.class`\1`')
echo Running $class
java $class
done
Running OriginalArrayTimingTest
Avg: 18528
Running UpdatedArrayTimingTest
Avg: 41111273
Running LinkedListTimingTest
Avg: 41340483
显然,你最初的担忧是由@meriton指出的错字造成的,你在问题中已经纠正了。我们可以看到,对于您的测试用例,数组和LinkedList的行为几乎相同。一般来说,LinkedList上的插入非常快。既然你用meriton的变化更新了你的问题,但没有更新你的说法,前者比后者快得多,那么你不再清楚你在问什么;但是我希望你现在可以看到,在这种情况下,两种数据结构的行为都相似。