Array / Vector作为方法参数

时间:2014-08-18 09:14:37

标签: java performance vector

我一直认为我们应该在Java中使用Vector,并且没有性能问题,这当然是正确的。我正在编写一种计算MSE(均方误差)的方法,并注意到它非常慢 - 我基本上是传递了值的向量。当我切换到Array时,速度提高了10倍,但我不明白为什么。

我写了一个简单的测试:

public static void main(String[] args) throws IOException {

    Vector <Integer> testV = new Vector<Integer>();
    Integer[] testA = new Integer[1000000];
    for(int i=0;i<1000000;i++){
        testV.add(i);
        testA[i]=i;
    }

    Long startTime = System.currentTimeMillis();
    for(int i=0;i<500;i++){
        double testVal = testArray(testA, 0, 1000000);
    }
    System.out.println(String.format("Array total time %s ",System.currentTimeMillis() - startTime));

    startTime = System.currentTimeMillis();
    for(int i=0;i<500;i++){
        double testVal = testVector(testV, 0, 1000000);
    }
    System.out.println(String.format("Vector total time %s ",System.currentTimeMillis() - startTime));

}

调用以下方法:

public static double testVector(Vector<Integer> data, int start, int stop){
    double toto = 0.0;
    for(int i=start ; i<stop ; i++){
        toto += data.get(i);
    }

    return toto / data.size();
}

public static double testArray(Integer[] data, int start, int stop){
    double toto = 0.0;
    for(int i=start ; i<stop ; i++){
        toto += data[i];
    }

    return toto / data.length;
}

阵列1确实快了10倍。这是输出:

数组总时间854 矢量总时间9840

有人可以解释一下为什么吗?我已经搜索了很长一段时间,但无法弄明白。 vector方法似乎是制作向量的本地副本,但我总是认为在Java中通过引用传递的对象。

4 个答案:

答案 0 :(得分:13)

我一直认为我们应该在Java中使用Vector,并且没有性能问题, - 错误。向量是线程安全的,因此它需要额外的逻辑(代码)来处理多个线程的访问/修改因此,它很慢。另一方面,数组不需要额外的逻辑来处理多个线程。您应该尝试ArrayList而不是Vector来提高速度

注意(根据您的评论):我每次运行该方法500次

这不是衡量java中性能/速度的正确方法。您至少应该进行预热,以便取消 JIT的效果。

答案 1 :(得分:4)

是的,这是微型基准测试不良的永恒问题。 Vector本身不是 SO 慢。

这是一个诀窍:
添加-XX:BiasedLockingStartupDelay=0,现在添加testVector&#34;魔法&#34;比以前快5倍!

接下来,将testVector打包到synchronized (data) - 现在几乎和testArray一样快。

您基本上是在HotSpot中测量对象监视器的性能,而不是数据结构。

答案 2 :(得分:0)

简单的事情。 Vector是线程安全的,因此需要同步来添加和访问。使用ArrayList,它也是由数组备份的,但它不是线程安全的,而且更快

注意: 如果您事先知道ArrayList,请提供元素的大小。由于在没有初始容量的普通ArrayList中,将使用Arrays copy

进行重新调整

没有初始容量性能的普通数组和ArrayList如果没有更大的元素那么会发生很大的变化

答案 3 :(得分:0)

代码不好,而不是list.get()而是在列表中使用迭代器。但阵列仍然会更快。