将混凝土集合浇铸到其界面的性能成本

时间:2011-09-05 14:52:53

标签: java performance casting

当我编写一些API时,它有时会使用Collection<Model>作为参数。当然,如果您知道ArrayList已足以处理所有用例,则可以使用ArrayList

我的问题是,例如在传递参数时将ArrayList<Model>强制转换为Collection<Model>是否会产生相当大的性能成本。

收藏尺寸是否也会影响铸造性能?有什么建议吗?

感谢Peter的回答。

我认为答案足以阻止我浪费时间去改变它。

修改

正如已接受的答案中所述,实际上是在调用接口方法时支付了费用。 保持这种灵活性并不是免费的。但成本并不是那么可观。

3 个答案:

答案 0 :(得分:6)

与大多数表演问题一样,答案是;编写清晰和简单的代码,应用程序通常也可以正常运行。

转换为接口可能需要大约10 ns(少于方法调用)根据代码的优化方式,它可能太小而无法测量。

泛型类型之间的转换是编译器时间检查,在运行时实际上没有发生任何事情。

当你施放时,它是更改的引用类型,所有引用都是相同的大小。他们指出的大小并不重要。

BTW:所有ArrayList对象都是相同的大小,所有的LinkedList对象大小相同,所有HashMap对象的大小都相同等。它们可以引用一个在不同集合中可以有不同大小的数组。


您可以看到未经过JIT编辑的代码差异。

public static void main(String... args) throws Throwable {
  ArrayList<Integer> ints = new ArrayList<>();
  for(int i=0;i<100;i++) ints.add(i);
  sumSize(ints, 5000);
  castSumSize(ints, 5000);
  sumSize(ints, 5000);
  castSumSize(ints, 5000);
}

public static long sumSize(ArrayList<Integer> ints, int runs) {
  long sum = 0;
  long start = System.nanoTime();
  for(int i=0;i<runs;i++)
    sum += ints.size();
  long time = System.nanoTime() - start;
  System.out.printf("sumSize: Took an average of %,d ns%n", time/runs);
  return sum;
}

public static long castSumSize(ArrayList<Integer> ints, int runs) {
  long sum = 0;
  long start = System.nanoTime();
  for(int i=0;i<runs;i++)
    sum += ((Collection) ints).size();
  long time = System.nanoTime() - start;
  System.out.printf("castSumSize: Took an average of %,d ns%n", time/runs);
  return sum;
}

打印

sumSize: Took an average of 31 ns
castSumSize: Took an average of 37 ns
sumSize: Took an average of 28 ns
castSumSize: Took an average of 34 ns

然而,差异可能是由于方法调用更昂贵。唯一的字节码差异是

invokevirtual   #9; //Method java/util/ArrayList.size:()I

invokeinterface #15,  1; //InterfaceMethod java/util/Collection.size:()I

一旦JIT优化了代码,就没有太大区别。运行时间足够长, -server JVM的时间下降到0 ns,因为它检测到循环没有做任何事情。 ;)

答案 1 :(得分:0)

与使用任何对象执行任何相比:绝对没有。

即使这样做,也要确保任何程序都涉及花费数百万更多时间的事情!

答案 2 :(得分:0)

收藏是interface。您始终必须提供具体的implementation,例如ArrayList。

通常会是这个

Collection<Model> myCollection = new ArrayList<Model>();

设计接口实际上是一种很好的做法,因此请使用Collection作为方法参数。