tof*_*arr 9 javascript optimization json google-chrome
我有一个(GIS)项目,向客户显示大量客户数据(数千条记录).在必要/可能/需要的地方,我们使用服务器端分页/过滤/数据操作,但有时将JSON格式的数据发送到客户端并让浏览器进行过滤是最有效的.
数据量很大,因此我们将其格式化以节省带宽和解析时间 - 而不是单个对象,我们首先发送包含属性名称的结构,然后在单个平面数组中发送值.在客户端上,我们在其他处理发生之前将其重建为更传统的json对象.例如:
{attrNames:["foo","bar"],values:[1,2,3,4,...]) -> [{foo:1,bar:2},{foo:3,bar:4},...]
Run Code Online (Sandbox Code Playgroud)
这样做的代码看起来有点像这样:
function toObjectArray(attrNames, values){
var ret = [];
var index = 0;
var numAttrNames = attrNames.length;
var numValues = values.length;
while(index < numValues){
var obj = {};
for(var a = 0; a < numAttrNames; a++){
obj[attrNames[a]] = values[index++];
}
ret.push(obj);
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)
鉴于属性可能会根据客户数据而变化,是否有办法利用V8等现代javascript引擎中的隐藏类进行此转换?我已经做了一些类似于我们的用例(http://jsfiddle.net/N6CrK/1/)的微基准测试,其中使用json使得使用隐藏类比如上构建对象快几个数量级.我可以使用"eval"创建对象来获得一些提升,但这感觉很难看(这在js小提琴中得到了证明).有没有更好的办法?也许使用Object.create的某些变体,或类似的东西?
我可以使用“eval”创建对象来获得一些提升,但这感觉很丑
使用构造函数有一种不太难看的方法Function。此外,可以通过立即将值分配给属性来完成进一步的优化,而不是像上面那样初始化它们,null然后再次迭代attrs数组adHoc。您只需将响应中获得的每一行(数组?字符串?字节什么的?)作为参数传递给工厂。
另外,我已将函数的创建factory移出函数create,以便只有一个函数会被实例化(并在对其进行足够多的调用后进行优化)。
测试循环中的相当多的时间都花在了 上getTotal,因此我以类似的方式对其进行了优化。在测试优化解决方案时不使用getTotalAdHoc会大大减少测量时间(您getTotalOptimum也可以使用它进行测试)。
var factory = new Function("arr", "return{"+attrs.map(function(n, i){
return n+":arr["+i+"]";
}).join(",")+"};");
var getSum = new Function("o","return "+attrs.map(function(n, i){
return "o."+n;
}).join("+")+";");
Run Code Online (Sandbox Code Playgroud)
我还没有尝试将完整的循环移到生成的代码中,这可以避免一些函数调用,但我认为这没有必要。