【发布时间】:2017-11-09 23:53:16
【问题描述】:
我有多个数字(至少 3 个),每个数字都可以针对由下限和上限获得的范围进行测试(我可以确定始终满足 lower <= upper 条件)。
现在有 lower[1...n]、x[1...n] 和 upper[1...n] 我的目标是优化性能...
我知道,看了this other Q&A here on StackOverflow 之后,我可以选择一个
(unsigned)(x[n]-lower[n]) <= (upper[n]-lower[n]) 表格
超越“经典”lower[n] <= x[n] && x[n] <= upper[n]
在这种情况下我需要使用 JavaScript,并且我知道我可以使用这种语言获得相同的“技巧”:
我很确定第二种方法会对性能产生最严重的影响,因此,在出发时将其排除在外,并且仅考虑第一种方法,我可以这样做:
// Example 1
function everything_is_in_range(lower, x, upper) {
return ( ((x[0]-lower[0]) >>> 0) <= (upper[0]-lower[0]) &&
((x[1]-lower[1]) >>> 0) <= (upper[1]-lower[1]) &&
...
((x[n-1]-lower[n-1]) >>> 0) <= (upper[n-1]-lower[n-1]) );
}
或者我可以这样做:
// Example 2
function everything_is_in_range(lower, x, upper) {
if ( ((x[0]-lower[0]) >>> 0) > (upper[0]-lower[0]) ) return false;
if ( ((x[1]-lower[1]) >>> 0) > (upper[1]-lower[1]) ) return false;
...
return ( ((x[n-1]-lower[n-1]) >>> 0) <= (upper[n-1]-lower[n-1]) );
}
我的问题是:
无符号移位在一般性能上是否不方便,所以我应该保留“经典”
lower[n] <= x[n] && x[n] <= upper[n]形式?如果我的第一个答案是否定的,那么哪种方法最有效?但更重要的是:你知道一个更好的建议吗?
附:我知道我可以通过以下方式使用 for 循环:
// Loop example
function everything_is_in_range(lower, x, upper) {
for (i=0; i<n; ++i) if ( ((x[i]-lower[i]) >>> 0) > (upper[i]-lower[i]) ) return false;
return true;
}
但是
这只是方便我写更少的代码,但它最终与第二种代码方法非常相似,不是吗?
我不想使用这种形式,因为所有值都可能碰巧作为单个分隔参数传递(这是我的真实案例,我正在处理 3 或 4 个数字 + 绑定范围集变量,我无法更改它)而不是值数组(如本例中)。
【问题讨论】:
-
Javascript 没有无符号数字的概念,因此您将无法利用该特殊技巧
-
function withinRange(num, begin, end){ if(num >= begin && num <= end){ return true; } else{ return false; } } -
将其设为“无符号”很可能会因为额外的转换步骤 stackoverflow.com/questions/14890994/… 而让它变慢一点,但我的猜测是函数调用本身会比比较有更大的开销跨度>
-
@PHPglue :我知道这种“经典”方式(顺便说一句
return (num >= begin && num <= end)会更好)但是,无论如何,我在问是否有可能对此进行优化,而且,我有多个在相同条件下测试的数字。 -
@Hamms :是的,我知道我不能应用相同的 C/C++ 技巧,但我也知道可以使用
Uint32Array(但我担心这会矫枉过正关于表演)或>>> 0技巧...我认为与“经典”方式相比,这是唯一的方法(我现在编辑了我的问题)
标签: javascript performance math optimization