Ron*_*ari 1 javascript performance eval
我正在从一系列过滤器创建一个where子句的字符串.
var where_clause_string = "(((true && ['SACRAMENTO','CITRUS HEIGHTS'].indexOf(raw_data[i]['city']) > -1) || (false && [].indexOf(raw_data[i]['city']) === -1)) || false)";
var raw_data_length = raw_data.length
, filtered_data = [];
for(var i = 0; i < raw_data_length; i++) {
if (eval(where_clause_string)) {
filtered_data.push(raw_data[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我迭代数据,这是一个对象数组,只返回通过真值测试的对象.
它给出了预期的结果,但性能却被搞砸了.过滤仅1500行需要约2-3秒.如果在不使用eval()的情况下对条件进行硬编码,则该过程非常快.
实现这一目标的替代方法是什么?
另一种方法是建立一个功能:
var where_clause_string = "(((true && ['SACRAMENTO','CITRUS HEIGHTS'].indexOf(raw_data[i]['city']) > -1) || (false && [].indexOf(raw_data[i]['city']) === -1)) || false)";
var evaler = new Function('raw_data', 'i', "return "+where_clause_string);
var raw_data_length = raw_data.length
, filtered_data = [];
for(var i = 0; i < raw_data_length; i++) {
if (evaler(raw_data, i)) {
filtered_data.push(raw_data[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
如果你想进一步,你可以使用的filter功能Array.prototype.它还可以确保函数生成不是去优化的可能原因(参见优化杀手):
var where_clause_string = "(((true && ['SACRAMENTO','CITRUS HEIGHTS'].indexOf(raw_data[i]['city']) > -1) || (false && [].indexOf(raw_data[i]['city']) === -1)) || false)";
var filtered_data = raw_data.filter(new Function(
'v', "return "+where_clause_string.replace(/raw_data\[i\]/g,'v')
));
Run Code Online (Sandbox Code Playgroud)
但通常最好从结构化数据开始,而不是要评估的原始字符串.使用我建议的功能可以获得更好的性能,但仍然可以获得字符串中代码的维护,可读性和安全性问题.也许它可能是这样的
var criterium = {
ok_cities:['SACRAMENTO','CITRUS HEIGHTS'],
nok_cities:[]
};
Run Code Online (Sandbox Code Playgroud)