gpt4 book ai didi

java - 在 Java : Is my benchmarking code wrong? 中对小型数组与列表进行基准测试

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:41:57 25 4
gpt4 key购买 nike

Disclaimer: I have looked through this question and this question but they both got derailed by small details and general optimization-is-unnecessary concerns. I really need all the performance I can get in my current app, which is receiving-processing-spewing MIDI data in realtime. Also it needs to scale up as well as possible.

我正在比较array小列表的大量读取性能到 ArrayList并且还只是掌握了变量。我发现数组胜过 ArrayList 2.5 倍,甚至胜过仅拥有对象引用。

我想知道的是:

  1. 我的基准测试还好吗? 我已经改变了测试顺序和运行次数,没有任何变化。我也使用毫秒而不是纳秒来无济于事。
  2. 我是否应该指定任何 Java 选项来最小化这种差异?
  3. 如果这种差异是真实的,在这种情况下我不应该更喜欢Test[]吗?至 ArrayList<Test>在这种情况下并放入转换它们所需的代码?显然我读的比写的多得多。

JVM 是 OSX 上的 Java 1.6.0_17,它肯定是在 Hotspot 模式下运行。

  public class ArraysVsLists {

static int RUNS = 100000;

public static void main(String[] args) {
long t1;
long t2;

Test test1 = new Test();
test1.thing = (int)Math.round(100*Math.random());
Test test2 = new Test();
test2.thing = (int)Math.round(100*Math.random());

t1 = System.nanoTime();

for (int i=0; i<RUNS; i++) {
test1.changeThing(i);
test2.changeThing(i);
}

t2 = System.nanoTime();
System.out.println((t2-t1) + " How long NO collection");

ArrayList<Test> list = new ArrayList<Test>(1);
list.add(test1);
list.add(test2);
// tried this too: helps a tiny tiny bit
list.trimToSize();

t1= System.nanoTime();

for (int i=0; i<RUNS; i++) {
for (Test eachTest : list) {
eachTest.changeThing(i);
}
}

t2 = System.nanoTime();
System.out.println((t2-t1) + " How long collection");


Test[] array = new Test[2];
list.toArray(array);

t1= System.nanoTime();

for (int i=0; i<RUNS; i++) {
for (Test test : array) {
test.changeThing(i);
}
}

t2 = System.nanoTime();
System.out.println((t2-t1) + " How long array ");

}
}

class Test {
int thing;
int thing2;
public void changeThing(int addThis) {
thing2 = addThis + thing;
}
}

最佳答案

微基准测试很难在像 Java 这样的平台上正确执行。您肯定必须将要进行基准测试的代码提取到单独的方法中,将它们作为预热运行几千次,然后进行测量。我已经这样做了(下面的代码),结果是通过引用直接访问的速度是通过数组的三倍,但集合仍然慢了 2 倍。

这些数字基于 JVM 选项 -server -XX:+DoEscapeAnalysis。如果没有 -server,使用集合的速度将急剧变慢(但奇怪的是,直接访问和数组访问要快很多,这表明发生了一些奇怪的事情)。 -XX:+DoEscapeAnalysis 为收集产生了另外 30% 的加速,但它是否适用于您的实际生产代码非常值得怀疑。

总的来说,我的结论是:忘记微基准测试吧,它们很容易产生误导。尽可能接近生产代码进行测量,而无需重写整个应用程序。

import java.util.ArrayList;

public class ArrayTest {

static int RUNS_INNER = 1000;
static int RUNS_WARMUP = 10000;
static int RUNS_OUTER = 100000;

public static void main(String[] args) {
long t1;
long t2;

Test test1 = new Test();
test1.thing = (int)Math.round(100*Math.random());
Test test2 = new Test();
test2.thing = (int)Math.round(100*Math.random());

for(int i=0; i<RUNS_WARMUP; i++)
{
testRefs(test1, test2);
}
t1 = System.nanoTime();
for(int i=0; i<RUNS_OUTER; i++)
{
testRefs(test1, test2);
}

t2 = System.nanoTime();
System.out.println((t2-t1)/1000000.0 + " How long NO collection");

ArrayList<Test> list = new ArrayList<Test>(1);
list.add(test1);
list.add(test2);
// tried this too: helps a tiny tiny bit
list.trimToSize();

for(int i=0; i<RUNS_WARMUP; i++)
{
testColl(list);
}
t1= System.nanoTime();

for(int i=0; i<RUNS_OUTER; i++)
{
testColl(list);
}

t2 = System.nanoTime();
System.out.println((t2-t1)/1000000.0 + " How long collection");


Test[] array = new Test[2];
list.toArray(array);

for(int i=0; i<RUNS_WARMUP; i++)
{
testArr(array);
}
t1= System.nanoTime();

for(int i=0; i<RUNS_OUTER; i++)
{
testArr(array);
}

t2 = System.nanoTime();
System.out.println((t2-t1)/1000000.0 + " How long array ");

}

private static void testArr(Test[] array)
{
for (int i=0; i<RUNS_INNER; i++) {
for (Test test : array) {
test.changeThing(i);
}
}
}

private static void testColl(ArrayList<Test> list)
{
for (int i=0; i<RUNS_INNER; i++) {
for (Test eachTest : list) {
eachTest.changeThing(i);
}
}
}

private static void testRefs(Test test1, Test test2)
{
for (int i=0; i<RUNS_INNER; i++) {
test1.changeThing(i);
test2.changeThing(i);
}
}
}

class Test {
int thing;
int thing2;
public void changeThing(int addThis) {
thing2 = addThis + thing;
}
}

关于java - 在 Java : Is my benchmarking code wrong? 中对小型数组与列表进行基准测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2227947/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com