不是答案,而是一些研究。
V8 引擎源码 (https://chromium.googlesource.com/v8/v8.git) 我在src/math.js 中找到了以下实现
Math.random
function MathRound(x) {
return %RoundNumber(TO_NUMBER_INLINE(x));
}
%RoundNumber 应指代src/runtime/runtime-maths.cc
RUNTIME_FUNCTION(Runtime_RoundNumber) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
isolate->counters()->math_round()->Increment();
if (!input->IsHeapNumber()) {
DCHECK(input->IsSmi());
return *input;
}
Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
double value = number->value();
int exponent = number->get_exponent();
int sign = number->get_sign();
if (exponent < -1) {
// Number in range ]-0.5..0.5[. These always round to +/-zero.
if (sign) return isolate->heap()->minus_zero_value();
return Smi::FromInt(0);
}
// We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
// should be rounded to 2^30, which is not smi (for 31-bit smis, similar
// argument holds for 32-bit smis).
if (!sign && exponent < kSmiValueSize - 2) {
return Smi::FromInt(static_cast<int>(value + 0.5));
}
// If the magnitude is big enough, there's no place for fraction part. If we
// try to add 0.5 to this number, 1.0 will be added instead.
if (exponent >= 52) {
return *number;
}
if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
// Do not call NumberFromDouble() to avoid extra checks.
return *isolate->factory()->NewNumber(Floor(value + 0.5));
}
数学.abs
function MathAbs(x) {
x = +x;
return (x > 0) ? x : 0 - x;
}
Node.JS 使用 V8 引擎,Chrome 也是如此
我的测试用例:
var randoms = [];
for (var i = 0; i < 100000; i++) {
randoms.push(Math.random() - 0.5);
}
for(var r = 0; r < randoms.length; r++) {
console.time('round');
for (var i = 0; i < randoms.length; i++) {
Math.round(randoms[i]);
}
console.timeEnd('round');
console.time('abs');
for (var i = 0; i < randoms.length; i++) {
Math.abs(randoms[i]);
}
console.timeEnd('abs');
}
结果:
- Chrome (42.0.2311.152 m) - Math.random 更快
- Node.JS (v0.10.29) - Math.abs 更快
想法
通过 V8 源,我希望 Math.abs 更快,它在 Node.JS 中,但不在 Chrome 中。
想法为什么?