将数字舍入到 3 的倍数
round numbers back to multiples of 3
我处于需要执行以下操作的情况:
if n = 0 or 1 or 2; return 0;
if n = 3 or 4 or 5; return 3;
if n = 6 or 7 or 8; return 6;
if n >= 9; return 9
我有以下代码工作正常。
var adjustNumberOfProducts = function(number) {
var output = 0;
switch(number) {
case 0:
case 1:
case 2:
output = 0;
break;
case 3:
case 4:
case 5:
output = 3;
break;
case 6:
case 7:
case 8:
output = 6;
break;
default:
output = 9
break;
}
return output;
}
我想知道是否有更优化(执行速度更快)的方法。
当然,你可以这样做:
var adjustNumberOfProducts = function(number) {
return Math.min(number - (number% 3),9);
}
你从数字中减去除以 3 的余数,使其成为 3 的倍数,然后取 9 之间的最小值以获得更高的值
您可以使用一些简单的数学运算来获得此输出:
function adjust( number ) {
return Math.min(Math.floor(number / 3) * 3, 9);
}
for ( var i = 0; i < 10; i++ )
document.write('For '+ i +': '+ adjust(i) + '<br>');
编辑:处理最多 9 个案例。
编辑:关于速度的说明。
虽然上面的代码在每次调用 adjust
时应用了更多的操作,但它的执行路径更少。 switch
语句有 9 种不同的执行路径供编译器考虑,而单个数学流程可以编译为更快的本机代码(使用 JIT 编译器)
如果您追求原始速度,那么某种查询可能就是您想要的;但是,通常的规则适用:使用分析器。
想到的查找类似于错误的:
// DOES NOT WORK: 0 is falsy in JavaScript
var adjustNumberOfProducts = function (number) {
return [0, 0, 0, 3, 3, 3, 6, 6, 6][number] || 9
}
但由于 0 在 JavaScript 中是假的,我们可以使用 T. J. Crowder 的(有趣的,不完全严肃的)"adjustment":
var adjustNumberOfProducts = function (number) {
return ([1, 1, 1, 4, 4, 4, 7, 7, 7][number] || 10) - 1
}
存在巨大的可读性损失,许多程序员在实际代码中看到这一点会完全畏缩(我认为 "MY EYES!" 可能是现代人的反应。)
我认为需要进行 jsperf 测试,以将这种邪恶的方法映射到您的 switch 语句和 Math.min(number - (number% 3),9)
技术。我会使用一些 asm.js 技术,例如与零进行按位或运算来强制进行整数数学运算,看看是否有帮助(尽管可能没有帮助)。
只需使用 i < 9 ? i - i % 3 : 9
即可获取您的值。
var i;
for (i = 0; i < 16; i++) {
document.write(i + ' ' + (i < 9 ? i - i % 3 : 9) + '<br>');
}
我处于需要执行以下操作的情况:
if n = 0 or 1 or 2; return 0;
if n = 3 or 4 or 5; return 3;
if n = 6 or 7 or 8; return 6;
if n >= 9; return 9
我有以下代码工作正常。
var adjustNumberOfProducts = function(number) {
var output = 0;
switch(number) {
case 0:
case 1:
case 2:
output = 0;
break;
case 3:
case 4:
case 5:
output = 3;
break;
case 6:
case 7:
case 8:
output = 6;
break;
default:
output = 9
break;
}
return output;
}
我想知道是否有更优化(执行速度更快)的方法。
当然,你可以这样做:
var adjustNumberOfProducts = function(number) {
return Math.min(number - (number% 3),9);
}
你从数字中减去除以 3 的余数,使其成为 3 的倍数,然后取 9 之间的最小值以获得更高的值
您可以使用一些简单的数学运算来获得此输出:
function adjust( number ) {
return Math.min(Math.floor(number / 3) * 3, 9);
}
for ( var i = 0; i < 10; i++ )
document.write('For '+ i +': '+ adjust(i) + '<br>');
编辑:处理最多 9 个案例。
编辑:关于速度的说明。
虽然上面的代码在每次调用 adjust
时应用了更多的操作,但它的执行路径更少。 switch
语句有 9 种不同的执行路径供编译器考虑,而单个数学流程可以编译为更快的本机代码(使用 JIT 编译器)
如果您追求原始速度,那么某种查询可能就是您想要的;但是,通常的规则适用:使用分析器。
想到的查找类似于错误的:
// DOES NOT WORK: 0 is falsy in JavaScript
var adjustNumberOfProducts = function (number) {
return [0, 0, 0, 3, 3, 3, 6, 6, 6][number] || 9
}
但由于 0 在 JavaScript 中是假的,我们可以使用 T. J. Crowder 的(有趣的,不完全严肃的)"adjustment":
var adjustNumberOfProducts = function (number) {
return ([1, 1, 1, 4, 4, 4, 7, 7, 7][number] || 10) - 1
}
存在巨大的可读性损失,许多程序员在实际代码中看到这一点会完全畏缩(我认为 "MY EYES!" 可能是现代人的反应。)
我认为需要进行 jsperf 测试,以将这种邪恶的方法映射到您的 switch 语句和 Math.min(number - (number% 3),9)
技术。我会使用一些 asm.js 技术,例如与零进行按位或运算来强制进行整数数学运算,看看是否有帮助(尽管可能没有帮助)。
只需使用 i < 9 ? i - i % 3 : 9
即可获取您的值。
var i;
for (i = 0; i < 16; i++) {
document.write(i + ' ' + (i < 9 ? i - i % 3 : 9) + '<br>');
}