gpt4 book ai didi

javascript - JS eval 非常慢需要更好的方法

转载 作者:行者123 更新时间:2023-11-28 20:16:03 28 4
gpt4 key购买 nike

我正在开发一个 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: "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

当这 2 个对象包含 obj1 100 条可能的路径和 obj2 1000 条可能的路径时,myclass 会生成 100,000 个要 eval 的语句。就是这样,它运行众所周知的 eval 很慢,但由于这些语句是字符串,我无法将其放入“if”

我尝试了一个测试代码,在 if 语句中使用了语句,它非常 - 非常快。我想使用 if 超过 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));

由于这些表达式可以是任何有效的 JS 表达式,我不能假设运算符。用户可以在表达式中自由使用任何类型的运算符(赋值、比较、算术、按位、逻辑、字符串或特殊运算符)。

例如:

"{source.cn}==={target.cid} && {target.name} != 'XX'"
or
"({source.cn}==={target.cid} || {source.cn}/100 === 1 )&& {target.name} != 'XX'"
or anything else.

我不想编写自己的表达式解析器。

请提供帮助(不使用 eval)1.替代方法(但不是 (new Function(expr)())2.使用“if”而不是“eval”的某种方式将使我的代码非常快。就像上面的测试证明的那样。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
}

当然,如果性能是一个问题,您将用简单的 for 替换 Array.forEach

关于javascript - JS eval 非常慢需要更好的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19168162/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com