Java异常的性能分析

欢迎进入Java社区论坛,与200万技术人员互动交流 >>进入

  新的pack方法和旧的实现差不太多–把一个字符串转化成一个尽可能小的Character/Integer/Long/Double/String类型,使得result.toString()。equals(orginalString)为true.

  <BR>public static Object strToObject( final String str )

  <BR>{

  <BR> if ( str == null || str.length() > 17 )

  <BR> { //out of Long range

  <BR> return str;

  <BR> }

  <BR> if ( str.equals( “” ) )

  <BR> return “”; //ensure interned string is returned

  <BR> if ( str.length() == 1 )

  <BR> return str.charAt( 0 ); //return Character

  <BR> //if starts with zero – support only “0” and “0.something”

  <BR> if ( str.charAt( 0 ) == ‘0’ )

  <BR> {

  <BR> if ( str.equals( “0” ) )

  <BR> return 0;

  <BR> if ( !str.startsWith( “0.” ) ) //this may be a double

  <BR> return str;

  <BR> }

  <BR>

  <BR> long res = 0;

  <BR> int sign = 1;

  <BR> for ( int i = 0; i < str.length(); ++i )

  <BR> {

  <BR> final char c = str.charAt( i );

  <BR> if ( c <= ‘9’ && c >= ‘0’ )

  <BR> res = res * 10 + ( c – ‘0’ );

  <BR> else if ( c == ‘.’ )

  <BR> {

  <BR> //too lazy to write a proper Double parser, use JDK one

  <BR> try

  <BR> {

  <BR> final Double val = Double.valueOf( str );

  <BR> //check if value converted back to string equals to an original string

  <BR> final String reverted = val.toString();

  <BR> return reverted.equals( str ) ? val : str;

  <BR> }

  <BR> catch ( NumberFormatException ex )

  <BR> {

  <BR> return str;

  <BR> }

  <BR> }

  <BR> else if ( c == ‘-‘ )

  <BR> {

  <BR> if ( i == 0 )

  <BR> sign = -1; //switch sign at first position

  <BR> else

  <BR> return str; //otherwise it is not numeric

  <BR> }

  <BR> else if ( c == ‘+’ )

  <BR> {

  <BR> if ( i == 0 )

  <BR> sign = 1; //sign at first position

  <BR> else

  <BR> return str; //otherwise it is not numeric

  <BR> }

  <BR> else //non-numeric

  <BR> return str;

  <BR> }

  <BR> //cast to int if value is in int range

  <BR> if ( res < Integer.MAX_VALUE )

  <BR> return ( int ) res * sign;

  <BR> //otherwise return Long

  <BR> return res * sign;

  <BR>}

  <BR>

  很惊讶吧,新的方法解析数字比JDK的实现快多了!很大一个原因是因为JDK在解析的最后,调用了一个支持的解析方法,像这样:

  public static int parseInt( String s, int radix ) throws NumberFormatException

  新的方法和旧的相比(注意方法调用的次数–对于非数字串pack只调用了1百万次,而别的情况能调用到千万级别):

  <BR>Pack: Made 100.000.000 iterations for string ‘12345’ : time = 12.145 sec

  <BR>Pack: Made 1.000.000 iterations for string ‘12345a’ : time = 23.248 sec

  <BR>strToObject: Made 100.000.000 iterations for string ‘12345’ : time = 6.311 sec

  <BR>strToObject: Made 100.000.000 iterations for string ‘12345a’ : time = 5.807 sec

  <BR>

  总结

  千万不要把异常当成返回码一样用,或者当作可能发生的事件(尤其是和IO无关的方法)往外抛。抛异常的代价太昂贵了,对于一般的方法,至少要慢百倍以上。

  如果你每条数据都需要解析,又经常会出现非数值串的时候,尽量不要用Number子类型的parse*/valueOf这些方法。为了性能考虑,你应当手动解析它们。

[1][2]

幸福就是重复。每天跟自己喜欢的人一起,

Java异常的性能分析

相关文章:

你感兴趣的文章:

标签云: