欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Beetl 性能揭秘 1 :如何输出一个整型变量 beetl 

程序员文章站 2022-06-06 13:16:51
...

常规来说,IO流提供了输出字符串(字符数组)的功能,所以,通常的整型输出应该是这样的代码:
String str = String.valueOf(12);
out.write(str);


对于模板引擎来说,输出整形变量很常见,事实上,这个地方有非常大的性能提高空间。我们只要分析这俩句话的源码,就能看出,如何提高io输出int性能。

对于第一句 String.valueOf 实际上调用了Integer.toString(int i) 方法,此方法原代码如下
public static String toString(int i) {
    if (i == Integer.MIN_VALUE)
        return "-2147483648";
    int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
    char[] buf = new char[size];
    getChars(i, size, buf);
    return new String(buf, true);
}


我们注意到,代码第5行分配了一个数组,对于任何一个高效的java工具来说,这都是个告警消息,分配数组耗时,垃圾回收也耗时

我们在分析out.write(str);代码,对于输出一个字符串,必须将字符串先转为字符串数组( 看到问题没有,这又回去了),熟悉String源码的同学都知道,这仍然是一个耗时操作,我们看一下源代码:

public char[] toCharArray() {
    // Cannot use Arrays.copyOf because of class initialization order issues
    char result[] = new char[value.length];
    System.arraycopy(value, 0, result, 0, value.length);
    return result;
}


如上代码,我们又发现了一次分配空间的操作,而且,还有一次字符串拷贝 System.arraycopy,这俩部又成了耗时操作

综合上面代码,我们就会发现,简单的一个int输出,除了基本的算法代码外,居然有俩次字符串的分配,还有一次数组copy。难怪性能低下(性能测试中确实这也是个消耗较多cpu的地方)。那么Beetl是如何改善的?

Beetl提供了一个专门的类IntIOWriter来处理字符串输出,如下关键代码片段:

public static void writeInteger(ByteWriter bw, Integer i) throws IOException
{

    if (i == Integer.MIN_VALUE)
    {
        bw.writeString("-2147483648");
        return;
    }

    int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
    char[] buf = bw.getLocalBuffer().getCharBuffer();
    getChars(i, size, buf);
    bw.writeNumberChars(buf, size);

}


如上代码,首先,我们可以看倒数第三行,并未分配字符素组,而是得到跟当前线程有关的一个char[]
其次,代码最后一行,直接就将此数组输出到IO流了,干净利索

综上所述,常规的输出int方法,除了常规算法外,需要俩次数组分配,和一次字符串拷贝操作。而Beetl则只需要常规算法即可输出,节省了俩次数组分配以及一次字符串copy操作。难怪性能这么好!

相关标签: beetl