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

【beetl 性能揭秘 2 (语言如何存取变量)】对于一个程序语言来说,访问变量是一个基本的操作,也是最频繁使用的操作。提高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 map = new HashMap(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倍

    推荐阅读