javascript eval()方法在过滤时会降低性能

时间:2015-04-21 08:37:04

标签: 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]);
  }
}

然后,我迭代数据,这是一个对象数组,只返回通过真值测试的对象。

它给出了预期的结果,但性能却被搞砸了。过滤仅1500行需要约2-3秒。如果在不使用eval()的情况下对条件进行硬编码,则该过程非常快。

实现这一目标的替代方法是什么?

2 个答案:

答案 0 :(得分:6)

另一种方法是建立一个功能:

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]);
  }
}

如果您想更进一步,可以使用filter的{​​{1}}功能。它还可以确保函数生成不是去优化的可能原因(参见Optimization Killers):

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')
));

答案 1 :(得分:0)

var raw_data_length = raw_data.length,
    filtered_data = [];
for (var i = 0; i < raw_data_length; i++) {
    // fill all param with values some may filled above the for statement
    var param1 = true,
        param2 = ['SACRAMENTO', 'CITRUS HEIGHTS'].indexOf(raw_data[i]['city']) > -1,
        param3 = false,
        param4 = [].indexOf(raw_data[i]['city']) === -1,
        param5 = false;

    if (param1 && param2 || param3 && param4 || param5) {
        filtered_data.push(raw_data[i]);
    }
}