Что быстрее: Math.abs(значение) или значение * -1?
Довольно просто, но я просто хочу знать, что быстрее.
Я думаю, что простое умножение числа на -1
намного быстрее, чем вызов предопределенного метода при условии, что вы уверены, что значение отрицательное.
Но если это так, то для чего нужна функция abs()
? Это просто для того, чтобы убедиться, что возвращаемое значение всегда будет положительным независимо от знака значения?
Ответы
Ответ 1
Обновлено Август 2012:
Я сделал некоторые профилирования с этими реализациями:
/* Test 1: */ b = Math.abs(a);
/* Test 2: */ b = abs(a); //local copy: abs = Math.abs;
/* Test 3: */ b = a < 0 ? a * -1 : a;
/* Test 4: */ b = a < 0 ? -a : a;
Я получил следующий результат в Windows 7. Значения нормализуются после самого быстрого результата для каждого браузера, чтобы упростить сравнение этого метода быстрее:
1:Math 2:abs 3:*-1 4:- 1.0= Version
Chrome 1.0 1.0 1.0 1.0 111ms 21.0.1180.75 m
Firefox 1.0 1.0 1.2 1.2 127ms 14.0.1
IE 1.4 1.0 1.1 1.0 185ms 9.0.8112
Opera 1.9 1.6 1.1 1.0 246ms 12.00
Safari 1.6 1.6 1.1 1.0 308ms 5.1.7
Вывод:
Когда я сделал этот тест 3 года назад, -а был самым быстрым, но теперь Math.abs(x) работает быстрее в Firefox! В Chrome abs(a)
и -a
получилось то же самое время, и это было всего лишь 3 мс разницы с самым медленным методом, когда я тестировал его с 10 000 000 номерами.
Моя рекомендация. Используйте Math.abs(a). Если вы находитесь в узком цикле и профилированием обнаружил, что он слишком медленный, вы можете использовать локальную ссылку на функцию abs:
var abs=Math.abs; //A local reference to the global Math.abs function
for (i=0;i<1234567890;++i) if ( abs( v[i] ) > 10) ++x;
Ответ 2
Я бы предложил выбрать метод, который более четко показывает ваше намерение, а не беспокоиться о производительности. В этом случае прирост производительности при умножении на -1, вероятно, минимален.
Когда вы используете Math.abs()
, очень ясно, что вы хотите получить положительное значение. Когда вы используете * -1
, это не ясно и требует больше исследований, чтобы определить, всегда ли входное значение отрицательно.
Ответ 3
Я полагаю, что это зависит от реализации, но Math.abs
может быть таким же простым, как:
function abs(x) {
return x < 0 ? x * -1 : x;
}
Итак, теоретически, он просто добавляет быстрый тест перед умножением.
Но да, отрицание отрицательного знака - единственная цель. Дело в том, что простой x * -1
также контрпродуктивен для положительных значений.
@olliej [комментарии]
True. Простое редактирование.;)
function abs(x) {
return Number(x < 0 ? x * -1 : x);
}
Ответ 4
Просто операция *-1
, вероятно, быстрее, но имейте в виду, что конечный результат отличается от результата для math.abs().
math.abs(-5)
и math.abs(5)
оба возвращают 5.
-5 * -1
также возвращает 5.
5 * -1
возвращает -5.
Итак, если вы абсолютно не уверены, что число отрицательно для начала, вам нужно сделать несколько тестов, которые стоят больше времени. Может также сделать math.abs().
Но действительно, если разница в производительности между abs() и * -1 имеет значение в вашей JS, у вас, вероятно, будут более серьезные проблемы.
Ответ 5
Вопрос стиля: зачем использовать a * -1
вместо -a
?
Кроме того, я согласен с тем, что вы должны использовать abs()
, если вы не знаете знака номера заранее. Мне было бы безразлично скорость, но читаемость.