`
deepinmind
  • 浏览: 450772 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
1dc14e59-7bdf-33ab-841a-02d087aed982
Java函数式编程
浏览量:41549
社区版块
存档分类
最新评论

Java可变参数的性能分析

 
阅读更多


可变长参数列表是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"进行校验,并重复一千万次:


   
checkDigits1varargs checkDigits1, Integer[]checkDigits2, int[]
0.304 sec0.219 sec 0.264 sec



总结

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


原创文章转载请注明出处:http://it.deepinmind.com

英文原文链接






2
0
分享到:
评论
2 楼 deepinmind 2014-04-23  
freezingsky 写道
关于可变参数方面的讨论,至少是在java1.5的时候就有了,我记得当时的说法是,可变参数其实本质就是数组。可以说是一种语法糖。


是的,其实就是语法糖。
1 楼 freezingsky 2014-04-22  
关于可变参数方面的讨论,至少是在java1.5的时候就有了,我记得当时的说法是,可变参数其实本质就是数组。可以说是一种语法糖。

相关推荐

    java类和对象之可变参数.docx

    Java 类和对象是编程语言的基础,而可变参数(Variable Argument)是 Java 为了解决方法接收不定数量参数的问题引入的一个特性。这个特性允许我们创建一个方法,它能接受一个可变数量的参数,而不是固定数量。这在...

    关于java中可变长参数的定义及使用方法详解

    5. **效率考虑**:可变长参数在内部使用数组实现,因此在大量参数传递时可能会有性能损失,尤其是如果参数需要进行深拷贝或者转换操作。 总的来说,Java的可变长参数提供了一种灵活的编程方式,使得我们可以方便地...

    java中的可变参数使用方法

    Java中的可变参数(Variable-Argument Parameters)是自Java 1.5版本引入的一个特性,它允许我们在方法声明中使用省略号(...)来表示一个可变数量的参数。这个特性大大增强了Java方法的灵活性,使得我们能够以更加...

    Java Varargs 可变参数用法详解

    Java Varargs(可变参数)是Java 1.5版本引入的一个特性,允许开发者在编写方法时可以接受任意数量的参数。Varargs是variable arguments的缩写,即变参,有时也简称为variable arguments。可变参数使得方法能够接受...

    javacore分析工具

    JavaCore分析工具是一种在Java应用程序出现问题时,...总之,JavaCore分析工具是Java开发和运维过程中不可或缺的诊断工具,它能够帮助开发者深入理解JVM内部工作原理,有效地解决性能问题,保障Web应用程序的稳定运行。

    解决JAVA服务器性能问题研究分析.doc

    总的来说,解决Java服务器性能问题涉及多个层面,包括但不限于:创建真实的负载模拟环境,选择合适的性能分析工具,监测和优化内存使用,处理同步竞争,以及持续跟踪性能变化。只有通过系统的分析和测试,才能找到并...

    java编程规范-性能篇

    这是因为String是不可变的,每次`+`操作都会创建新的String对象,对于大量的字符串拼接,这会导致大量的内存分配和垃圾回收。 6. **使用JDK自带API**: - 尽量使用JDK自带的API函数,因为它们通常在性能和可靠性上...

    Java中实现参数名ASCII码从小到大排序(字典序).doc

    相比`String`对象,使用`StringBuilder`在处理大量字符串连接时能提供更好的性能,因为`String`是不可变的,每次修改都会创建新的对象,而`StringBuilder`可以在原地修改字符串,避免了不必要的内存分配。...

    Java程序性能优化 让你的Java程序更快、更稳定附本书示例代码(清晰版)

    优化过程中,应该遵循“测量先行”的原则,使用如JProfiler、VisualVM等工具进行性能分析,找出瓶颈所在,而不是盲目猜测和修改。此外,优化应避免过度优化,过度优化可能会导致代码变得难以理解和维护。 书中的一...

    20_集合_第3天(Map、可变参数、Collections)_讲义

    可变参数是Java 5引入的一个特性,它允许函数接收不定数量的参数。可变参数在声明时以省略号(….)表示,如`public void myMethod(int... numbers)`。在函数内部,可变参数会被处理为一个数组,可以方便地进行迭代或...

    Java行为参数化功能详解.pdf

    Java行为参数化是一种编程技术,它允许我们将行为(如条件检查)作为参数传递给方法,从而使代码更加灵活和可重用。...在实际项目中,结合性能分析和调优,这种技术可以帮助我们构建更高效、更易维护的应用程序。

    Java调用存储过程--传入集合参数

    在Java应用中,调用数据库存储过程时,往往需要处理复杂的参数传递,特别是当参数为集合类型时,这一过程变得更加具有挑战性。本文将深入探讨如何在Java中有效地调用存储过程,并向其传递集合参数,主要聚焦于Oracle...

    java性能的优化-如何提高java运行效率

    尤其是在服务器端应用中,虽然Java技术如JSP、Servlet和EJB等在服务端编程中占有一席之地,但性能问题仍然是不可忽视的问题。 【性能优化基础】 1. 性能定义: - 运算性能:哪种算法执行效率更高。 - 内存分配:...

    java问题定位技术+性能优化

    - JProfiler: 更高级的性能分析工具,支持更详细的分析。 - **2.2.6 跟性能相关的JVM参数** - `-Xms`/`-Xmx`: 设置堆内存的初始值和最大值。 - `-XX:+UseG1GC`: 启用G1垃圾收集器,提高垃圾回收效率。 - **2.3 ...

    如何来提高自己对java的性能上提高

    - **避免使用`==`比较字符串**:Java中的字符串是不可变对象,用`equals()`方法比较更高效。 - **使用StringBuilder或StringBuffer进行字符串拼接**:在循环中,使用`+`连接字符串会创建多个中间对象,效率较低。 ...

    Java零基础-参数传递-2.md

    在Java中,可变参数列表允许方法接受任意数量的同类型参数。这通常在参数的数量不确定的情况下非常有用。 - **Varargs 的使用**:在方法声明中,可以通过在参数类型后加上三个点(`...`)来声明一个可变参数列表。...

    java提高性能.pdf

    7. 字符串操作:字符串在Java中是不可变的,对字符串的操作可能会影响性能。例如,“Stringstr="hello";Stringstr=newString("hello");”和“StringBufferStringBufferbuffer=newStringBuffer(1000);”分别展示了不...

    Java性能优化技巧集锦

    3. **字符串操作**:字符串是不可变对象,频繁的字符串连接操作应使用StringBuilder或StringBuffer(多线程环境下使用后者)。避免不必要的字符串复制。 4. **方法与类的设计**:尽可能减少方法的粒度,提高复用率...

    Java基础:减少对象的创建提高java性能

    此外,由于它们的状态不可改变,JVM有时可以对不可变对象进行优化,如缓存或共享相同的实例,称为“字符串池”。 对于需要频繁修改的字符串操作,如搜索、替换或拼接,使用`StringBuilder`或`StringBuffer`类通常会...

    一种实时Java程序的WCET分析新方法研究.pdf

    【标题】: "一种实时Java程序的WCET分析新方法研究" 【摘要】: 这篇文章探讨...总的来说,这篇研究为实时Java应用程序的性能分析提供了新的工具和方法,有助于提高实时系统的可靠性,并推动Java在实时系统领域的应用。

Global site tag (gtag.js) - Google Analytics