beetl 性能揭秘 2 :语言如何存取变量

不问归期 提交于 2020-03-01 13:37:17
对于一个程序语言来说,访问变量是一个基本的操作,也是最频繁使用的操作。提高Beetl访问变量的效率,将整体上提高Beetl的性能,本文介绍了Beetl是如何访问变量的。
首先看一个简单的例子:
var a = "hi";
print(a);





第一行定义a变量,第二行引用a变量打印输出,通常设计下,可以在变量定义的时候将变量保存到map里,需要用的时候根据变量名取出。因此上诉代码可以翻译为java的类似如下代码:
context.put("a","hi");

print(context.get("a");

尽管我们都知道Map存取都是非常快的,但还有没有更快的方式呢,答案就是有,那就是数组,数组的存取更快,通过如下代码可以看出, 数组的存放元素的速度是Map的10倍,读取那就更快了,是100倍

String value1 = "a";
    String value2 = "b";
    String value3 = "c";
    String key1 = "key1";
    String key2 = "key2";
    String key3 = "key3";
    String[] objects = new String[3];
    int loop = 10000 * 5000;
            //计算数组存消耗的时间
    Log.key1Start();
    for (int i = 0; i < loop; i++) {
        objects[0] = value1;
        objects[1] = value2;
        objects[2] = value3;

    }
    Log.key1End();

    Map<String, String> map = new HashMap<String, String>(3);
            //计算Map存消耗的时间
    Log.key2Start();
    for (int i = 0; i < loop; i++) {
        map.put(key1, value1);
        map.put(key2, value2);
        map.put(key3, value3);

    }
    Log.key2End();

            // 计算数组取消耗的时间
    Log.key3Start();
    for (int i = 0; i < loop; i++) {
        value1 = objects[0];
        value2 = objects[1];
        value3 = objects[2];

    }
    Log.key3End();
            // 计算map取消耗的时间
    Log.key4Start();
    for (int i = 0; i < loop; i++) {
        value1 = map.get(key1);
        value2 = map.get(key2);
        value3 = map.get(key3);

    }
    Log.key4End();
            //打印性能统计数据
    Log.display("使用数组设置", "使用Map设置", "使用数组读取", "使用map读取");





控制台输出:

======================
使用数组设置=139 百分比,Infinity
使用Map设置=1020 百分比,Infinity
使用数组读取=3 百分比,Infinity
使用map读取=767 百分比,Infinity

(代码参考 https://github.com/javamonkey/  ... .java

Beetl在修改2.0引擎的时候,对变量存取进行了优化,使用一个一维数组来保存变量,如本文开头的例子
,在2.0引擎里,翻译成如下代码:
context.vars[varNode.index] = "hi"
print(context.vars[varNode.index]);





那么,Beetl又是怎么做给模板变量分配索引呢?如下代码是如何分配索引的?
var a = 0;
{
var b = 2;   
}
{
var c = 2;
} 

var d =1 ;





虽然有4个变量,但维护这些变量的只需要一个一维数组就可以,数组长度是3 
节点a,d,c,b的index是0,1,2,2,就是子context(进入block后) 会在上一级context后面排着:先分配顶级变量a和d,赋上索引是0和1,然后二级变量b赋值索引是2,对于同样是二级的变量c,也可以赋上索引为2,因为变量b的已经出了作用域。

经过性能测试证明2.0的性能关于变量赋值和引用,综合提高了50倍
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!