Java的varargs性能 [英] Java's varargs performance

查看:85
本文介绍了Java的varargs性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编码我来检查Java的vararg性能。



我写下以下测试代码:

  public class T {

public static void main(String [] args){

int n = 100000000;
String s1 = new String();
String s2 = new String();
String s3 = new String();
String s4 = new String();
String s5 = new String();

long t = System.currentTimeMillis();
for(int i = 0; i< n; i ++){
foo();
}
System.err.println(System.currentTimeMillis() - t);


t = System.currentTimeMillis();
for(int i = 0; i< n; i ++){
baz(s1,s2,s3,s4,s5);
}
System.err.println(System.currentTimeMillis() - t);

t = System.currentTimeMillis();
for(int i = 0; i< n; i ++){
bar(s1,s2,s3,s4,s5);
}
System.err.println(System.currentTimeMillis() - t);

}

static void foo(){
}

static void bar(String a1,String a2,String a3,String a4,字符串a5){
}

static void baz(String ... a){
}
}

在我的机器上,平均输出为:

  78 
4696
78

似乎将变量传递给方法是没有费用?!好!



但使用varags的速度要慢60倍!为什么?



解释可能是程序必须在堆上创建数组,并且GC需要花费时间。但是对于较少的循环,我仍然得到输出:

  0 
62
0

什么是花费这个额外的时间,无论如何编译器都有解决这个问题的所有信息到一个修复变量调用...... / p>

我不打算对此进行优化,但我发现这很好奇......



更新



我添加了新测试

  t = System.currentTimeMillis的(); 
for(int i = 0; i< n; i ++){
baz(s1);
}
System.err.println(System.currentTimeMillis() - t);

这一个参数版本仍然慢30倍。也许在场景后面有一个ArrayList.toArray()?



因此请注意代码中不需要的varags方法和重构来修复长度。这可能是一种性能提升。

解决方案

参数的静态列表与数组完全不同。当你以这种方式传递它们时,编译器为引用保留空间并在调用方法时填充它们。



Varargs相当于数组。要调用此类方法,必须在运行时创建并填充数组。这就是你观察差异的原因。



String [] String ... 是同义词。如果你比较它们,你会看到相同的表现。


Coding i came around to check for the vararg performance of Java.

I write following test code:

public class T {

    public static void main(String[] args) {

        int n = 100000000;
        String s1 = new String("");
        String s2 = new String("");
        String s3 = new String("");
        String s4 = new String("");
        String s5 = new String("");

        long t = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            foo();
        }
        System.err.println(System.currentTimeMillis() - t);


        t = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            baz(s1, s2, s3, s4, s5);
        }
        System.err.println(System.currentTimeMillis() - t);

        t = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            bar(s1, s2, s3, s4, s5);
        }
        System.err.println(System.currentTimeMillis() - t);

    }

    static void foo() {
    }

    static void bar(String a1, String a2, String a3, String a4, String a5) {
    }

    static void baz(String... a) {
    }
}

On my machine the average output is:

78
4696
78

Seems that pass variables to methods is at no cost ?! Good !

But using varags is 60x slower ! Why ?

An explanation could be that the program must create the array on the heap and the time is spend by GC. But for less loops i still get as output:

0
62
0

What is spending this extra time for and anyway the compiler has all information to resolve this to a fix variable call ...

Its not my intention to optimize for that, but i found this curious ...

Update

I added a new test

t = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
    baz(s1);
}
System.err.println(System.currentTimeMillis() - t);

And this one argument version is still 30x slower. Maybe there is an ArrayList.toArray() behind the scene ?

So be aware of no-needed varags methods in your code and refactor to fix length. That could be a perfomance boost.

解决方案

Static list of arguments is quite different from an array. When you pass them that way, compiler reserves space for the references and populates them when the method is called.

Varargs is an equivalent of array. To call such a method, it's necessary to create and populate array at run time. That's why you observe the difference.

String[] and String... are synonyms. If you compared them, you should see identical performance.

这篇关于Java的varargs性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆