Javascript JS评估非常慢,需要更好的方法
我正在开发一个API,它将接受2个对象和一个表达式,并执行假语句过滤。返回第三个对象,该对象将仅包含表达式计算为true的那些数据集Javascript JS评估非常慢,需要更好的方法,javascript,performance,google-chrome,loops,webkit,Javascript,Performance,Google Chrome,Loops,Webkit,我正在开发一个API,它将接受2个对象和一个表达式,并执行假语句过滤。返回第三个对象,该对象将仅包含表达式计算为true的那些数据集 var obj1 = [ {cn: 101, name: "AA", seq:1}, {cn: 106, name: "BB", seq:2} ]; var obj2 = [ { cid: 100, name: "XX", locator: "r" }, { cid: 101, name:
var obj1 = [
{cn: 101, name: "AA", seq:1},
{cn: 106, name: "BB", seq:2}
];
var obj2 = [
{ cid: 100, name: "XX", locator: "r" },
{ cid: 101, name: "AA", locator: "p"},
{ cid: 507, name: "TT", locator: "r"}
];
var output = MyClass.filter(obj1, obj2, "{source.cn}==={target.cid}");
obj1 is source object
obj2 is target object
expected output is:
output = [
{ cid: 101, name: "AA", locator: "p"}
];
由于我的类是一个泛型类,它应该能够接受任意两个对象(任意结构和深度)并执行任意有效的javascript表达式。因此,我找到给定表达式的路径并准备表达式列表
source[0]["cn"]===target[0]["cid"]
source[0]["cn"]===target[1]["cid"]
source[0]["cn"]===target[2]["cid"]
source[1]["cn"]===target[0]["cid"]
source[1]["cn"]===target[1]["cid"]
source[1]["cn"]===target[2]["cid"]
得到表达式后,我对每个表达式进行评估,并过滤掉错误的表达式
eval(source[0]["cn"]===target[0]["cid"]) >>>>>EVAL RESULT>>>>> false
eval(source[0]["cn"]===target[1]["cid"]) >>>>>EVAL RESULT>>>>> true
eval(source[0]["cn"]===target[2]["cid"]) >>>>>EVAL RESULT>>>>> false
eval(source[1]["cn"]===target[0]["cid"]) >>>>>EVAL RESULT>>>>> false
eval(source[1]["cn"]===target[1]["cid"]) >>>>>EVAL RESULT>>>>> false
eval(source[1]["cn"]===target[2]["cid"]) >>>>>EVAL RESULT>>>>> false
当这两个对象包含例如obj1 100条可能路径和obj2 1000条可能路径时,myclass将生成100000条语句以进行评估。就是这样,它一直运行,众所周知,eval很慢,但由于这些语句是字符串,所以我无法将其放入“if”
我尝试了一个测试代码,在if语句中使用语句,速度非常非常快。我想用if over eval
我的测试代码如下所示:
var before = Date.now();
var str, result, results = [], m, n;
for(var i = 0, j=0; i <100000, j<100000; ++i,++j ){
str = i + "===" + j;
//eval(str)
if(i === j) {
result = true;
} else {
result = false;
}
}
var after = Date.now();
console.log("Time: ", (after - before));
我不想写我自己的表达式解析器
请提供帮助(不使用eval)
1.替代方法(但不是(新函数(expr)()
2.使用“如果”超过“评估”的某种方法将使我的代码速度非常快。正如上面的测试所证明的。
3.在不影响需求的情况下加快速度的任何其他方法。(是的,目标对象中可能有多个匹配项)
提前感谢。首先可能不需要评估 只需从传递字符串切换
var output = MyClass.filter(obj1, obj2, "{source.cn}==={target.cid}");
使用函数
function comparator(source, target) {
return source.cn===target.cid
}
var output = MyClass.filter(obj1, obj2, comparator);
您的过滤器将非常简单
function filter(array1,array2, comparator) {
var ret = []
array1.forEach(function(source) {
array2.forEach(function(target) {
if (comparator(source,target)) ret.push(source)
}
})
return ret
}
当然,如果性能是一个问题,那么您将使用simple
for
替换Array.forEach
只需从传递字符串切换
var output = MyClass.filter(obj1, obj2, "{source.cn}==={target.cid}");
使用函数
function comparator(source, target) {
return source.cn===target.cid
}
var output = MyClass.filter(obj1, obj2, comparator);
您的过滤器将非常简单
function filter(array1,array2, comparator) {
var ret = []
array1.forEach(function(source) {
array2.forEach(function(target) {
if (comparator(source,target)) ret.push(source)
}
})
return ret
}
当然,如果性能是一个问题,您将使用simple
for
替换数组。感谢vittore,obj1和obj2可以是任何对象2完全不同的结构,因此不能假定为数组。“cn”和“cid”将处于任何深度级别。我喜欢尝试传递回调部分。感谢vittore,obj1和obj2可以是任何对象2完全不同的结构,因此不能假设为数组。“cn”和“cid”将处于任何深度级别。我喜欢尝试传递回调部分。