微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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,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) {
    }
}

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

78
4696
78

似乎将变量传递给方法是免费的!好的!

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

一个解释可能是程序必须在堆上创建数组,时间是由GC花费的.但是对于较少的循环,我仍然可以得到输出

0
62
0

什么是花费这个额外的时间,无论如何,编译器有所有信息来解决这个修改变量调用

这不是我打算优化的,但我发现这个好奇…

更新

添加一个新的测试

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 …是同义词.如果你比较他们,你应该看到相同的表现.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐