Java可变参数的性能分析

标签: java 参数 性能分析 | 发表时间:2014-04-22 16:57 | 作者:
出处:http://it.deepinmind.com

可变长参数列表是Java 5中的一个新特性。如果方法需要传入多个同类型参数的话,这个功能就非常有用。比如说,Java 5之前如果要写一个方法来将所有入参打印到控制台上的话,它的代码会是这样的:

   public static void printAll( final Object[] args )
{
    for ( int i = 0; i < args.length; ++i )
        System.out.println( args[ i ] );
}

方法调用的话会是这样:

   printAll( new Object[] { new Integer( 75 ), new Date(), "String" + 50 } );

Java 5增加了对可变参数的支持。这个方法现在看起来就简单多了(译注:这里看起来简单难道不是因为新的for循环?):

   public static void printAllNew( final Object... args )
{
  for ( final Object arg : args )
      System.out.println( arg );
}

它的调用也变得更简单了(由于支持了可变参数列表):

   printAllNew( 75, new Date(), "String" + 50 );

最重要的一点就是,其实什么都没有发生变化。这一切其实都隐藏在背后——这些数组还是会创建的。因此如果你在代码里的内部循环中使用了可变长参数,最好确保参数列表中的所有的值都是常量。你可能经常会使用一组预定义的常量,对一个输入值进行校验。

比如说,传给你的日期串是'yyyy/mm/dd'的格式,而时间的格式是'hh:mm:ss'。如果有个方法能检查一个输入串在指定的位置只包含数字的话就会方便许多。最直接的方式当然是这么写:

   public static boolean checkDigits1( final String s, final Integer... positions )
{
    for ( final Integer pos : positions )
        if ( !Character.isDigit( s.charAt( pos ) ) )
            return false;
    return true;
}

它可以这么进行调用:

   checkDigits1( "2011/10/12", 0, 1, 2, 3, 5, 6, 8, 9 )

不幸的是,每次调用都会创建一个Integer数组(实际上是双倍的开销——首先会创建一个Integer数组,然后把每个int参数转化成一个Integer对象,再放到数组里)。如果显式地声明这个数组并将它传给方法的话会高效很多:

   private static final Integer[] DATE_POS = { 0, 1, 2, 3, 5, 6, 8, 9 };
...
checkDigits1( "2011/10/12", DATE_POS )

还有一个问题就是我们要不要使用int来代替Integer,因为String.charAt()方法需要的是一个int参数,因此所有的Integer参数都会进行拆箱操作。但是,由于某个未知原因,在这里使用int还会更慢一些:

   public static boolean checkDigits2( final String s, final int[] positions )
{
    for ( int i = 0; i < positions.length; ++i  )
        if ( !Character.isDigit( s.charAt( positions[ i ] ) ) )
            return false;
    return true;
}

新老的for循环写法的性能都是一样的。我们来对日期串"2011/10/12"进行校验,并重复一千万次:

checkDigits1 varargs checkDigits1, Integer[] checkDigits2, int[]
0.304 sec 0.219 sec 0.264 sec

总结

由于可变参数可以减少代码量,因此对于大多数程序来说是非常适用的,不过如果所有的参数都是已知的常量的话,最好使用预编译的数组来代替它。

原创文章转载请注明出处: Java可变参数的性能分析

英文原文链接

相关 [java 参数 性能分析] 推荐:

Java可变参数的性能分析

- - Java译站
可变长参数列表是Java 5中的一个新特性. 如果方法需要传入多个同类型参数的话,这个功能就非常有用. 比如说,Java 5之前如果要写一个方法来将所有入参打印到控制台上的话,它的代码会是这样的:. Java 5增加了对可变参数的支持. 这个方法现在看起来就简单多了(译注:这里看起来简单难道不是因为新的for循环.

Java异常的性能分析

- - Java译站
在Java中抛异常的性能是非常差的. 通常来说,抛一个异常大概会消耗100到1000个时钟节拍. 通常是出现了意想不到的错误,我们才会往外抛异常. 也就是说,我们肯定不希望一个进程一秒钟就抛出上千个异常. 不过有时候你确实会碰到有些方法把异常当作事件一样往外抛. 我们在 这篇文章中已经看到一个这样的典范):sun.misc.BASE64Decoder之所以性能很差就是因为它通过抛异常来对外请求道,”我还需要更多的数据“:.

Java 8并行操作的性能分析

- - Java译站
当我在写这篇博客的时候,我还在为昨天聚会上说过的话感到尴尬,当时大家看我跟看怪物一样. 好吧,不过所幸的是我并不孤单——Java 8它也很擅长这口. Java 8中一个关键的新特性就是它支持并行数组操作. 你可以使用lambda表达式来进行排序,过滤,分组等操作,它能自动的发挥多核架构的优势. 带来的好处就是作为一名Java开发人员,你只需很小的工作量就可以立马获得性能的提升.

java socket参数详解:BackLog

- - 开源软件 - ITeye博客
 java socket参数详解:BackLog. 输入连接指示(对连接的请求)的最大队列长度被设置为 backlog 参数. 如果队列满时收到连接指示,则拒绝该连接. backlog参数必须是大于 0 的正值. 如果传递的值等于或小于 0,则假定为默认值. 经过测试这个队列是按照 FIFO(先进先出)的原则.

Java虚拟机(JVM)参数简介

- - ITeye博客
Java虚拟机(JVM)参数简介. 在Java、J2EE大型应用中,JVM非标准参数的配置直接关系到整个系统的性能. JVM非标准参数指的是JVM底层的一些配置参数,这些参数在一般开发中默认即可,不需要任何配置. 但是在生产环境中,为了提高性能,往往需要调整这些参数,以求系统达到最佳新能. 另外这些参数的配置也是影响系统稳定性的一个重要因素,相信大多数Java开发人员都见过“OutOfMemory”类型的错误.

Java 6 JVM参数配置说明

- - Java - 编程语言 - ITeye博客
-XX:+

java参数传递机制浅析

- - CSDN博客编程语言推荐文章
java语言中,参数的传递只有一种机制,那就是 值传递. 下面将通过几个例子来说明java中的参数传递机制,这些例子基本涵盖了所有参数传递的情况. 结果当然很显然都是10,因为基本数据类型传递的是值的一份拷贝(副本),对副本操作不影响原始值.     2.1.对参数重新赋值:. 方法中的参数只是原始对象的一份拷贝,更准确的讲是地址的一份拷贝,故而对其进行重新赋值并不会影响原始对象.

JAVA性能优化 - IBMJDKJVM参数设置

- - 编程语言 - ITeye博客
 本文将描述IBM JDK下常用参数的设置.   -Xms:最小堆大小.   -Xmx:最大堆大小.   -Xminf and -Xmaxf:GC(垃圾回收)之后可用空间的最小值最大值.   -Xmine and -Xmaxe:堆增长的最小最大值.   -Xmint and -Xmaxt:垃圾回收占时间整个运行时间的比例,默认是5%.

Java 中的可选参数 | Java Debug 笔记

- - 掘金 后端
本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看. 如何使用 Java 中的可选参数. 一定程度上来讲, varargs (即长度可变的参数)可以做到这一点. 除此之外,必须提供方法声明中的所有变量. 如果想让变量是可选的,那么可以通过重载的方式,此时重载的方法是不带参数的.

Java 6 JVM参数选项大全(中文版)

- LightingMan - 淘宝JAVA中间件团队博客
本文是基于最新的SUN官方文档Java SE 6 Hotspot VM Options 编写的译文. 主要介绍JVM中的非稳态选项及其使用说明. 为了让读者明白每个选项的含义,作者在原文基础上补充了大量的资料. 希望这份文档,对正在研究JVM参数的朋友有帮助. 另外,考虑到本文档是初稿,如有描述错误,敬请指正.