我有一个用例,我想查看一组数据是否匹配一个非常小的条件列表(为了论证,让我们说它小于20)。
我在客户端和服务器端(NodeJS)上执行JavaScript。我试图在两个选项(或任何其他选项)之间进行选择,并且不确定复杂性和计算时间有多么不同。我觉得他们可以忽略不计。
选项1:迭代条件列表
var conditions = [{
prop: 'a', check: '===', val: 'foo'
}, {
prop: 'b', check: '!==', val: 'bar'
}];
for (var i=0;i<conditions.length;i++) {
// Check conditions[i]
if (conditions[i].check === '===') {
if (data[conditions[i].prop] === conditions[i].val) {
// Keep checking
} else {
// Fail
}
} else if (conditions[i].check === '!==') {
...
}
}
选项2:将条件转换为JavaScript
if (data.a === 'foo' && data.b !== 'bar' && ... ) {
// Passes
}
选项1在O(n)中执行,而选项2在O(1)中从技术上讲,但这对于如此小的列表确实很重要,尤其是当您考虑执行JSON.eval()
所需的时间时和/或为该帐户提供唯一代码?
答案 0 :(得分:2)
首先eval
错误(大多数情况下)。
代码看起来很丑,所有这些如果条件但性能明智,如果条件不满足,它们中的代码将不会运行。所以最终解析需要更长的时间,但不能运行它。
如果您的迭代次数很低,那么使用第一个示例时的性能不应该成为问题。
当您想要精确测量时间使用时,您可以编写一个测试。
答案 1 :(得分:1)
一般来说,&#34;编译&#34;你的条件清单要比#34;解释&#34;快得多。他们,如果这真的很重要;你需要进行基准测试以确定它是否存在。你可以&#34;编译&#34;使用eval
或使用Function
构造函数。但是,只有在真正需要时才应采取这种方法,这应该是一种罕见的情况。
但我不确定你为什么要发明这种小语言来检查;通过&#34;语言&#34;,我指的是{prop: 'a', check: '===', val: 'foo'}
形式的东西。你必须写那些东西;然后你必须解析&#34;他们在运行时;那么你必须在运行时执行它们。 JavaScript已经有一种非常好的方法来封装这些功能;它们被称为&#34;功能&#34;。除了其他优点之外,如果调用足够的次数,则可以通过引擎优化这些功能。
基于函数的问题解决方法是写:
var conditions = [
data => data.a === 'foo',
data => data.b !== 'bar'
];
for (var i=0;i<conditions.length;i++) {
// Check conditions[i]
if (conditions[i](data)) {
// Keep checking
} else {
// Fail
}
...
}
}
或者更通俗地说
conditions.every(condition => condition(data))
无论你如何写这个,条件的数量基本上都是O(n)
。正在进行的比较/测试的数量不会改变。问题是执行这些测试的速度,而不是大O订单。