Довольно просто, но я просто хочу знать, что быстрее.
Я думаю, что простое умножение числа на -1 намного быстрее, чем вызов предопределенного метода, при условии, что вы уверены, что значение отрицательное.
Но в таком случае для чего нужна функция abs()? Это просто для того, чтобы возвращаемое значение всегда было положительным, независимо от знака значения?
Быстрый ответ для людей будущего: ни то, ни другое.
..если вы не используете специальную функцию: jsperf.com/math-abs-vs-custom-abs-function, где Math.abs() значительно превосходит все остальное.
по этому тесту: jsben.ch/#/ZJRAv .. разницы почти не должно быть.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я полагаю, это зависит от реализации, но Math.abs может быть таким же простым, как:
function abs(x) {
return x < 0 ? x * -1 : x;
}
Так что теоретически он просто добавляет быстрый тест перед умножением.
Но да, исключение отрицательного знака - единственная цель. Дело в том, что простой x * -1 также контрпродуктивен для положительных значений.
@olliej [комментарии]
Правда. Хотя простое редактирование. ;)
function abs(x) {
return Number(x < 0 ? x * -1 : x);
}
Это неверно для технически, поскольку abs определяется как возвращаемое число. Если я сделал abs (true) или abs (false), я должен получить 0 или 1, тогда как ваша функция выдаст true или false. функция abs (x) {если (x <0) return -x; return + x; } должен работать, но я не на 100%, он будет правильно обрабатывать 0 / -0.
(Случайный факт: в текущих выпусках WebKit это на самом деле быстрее, чем при использовании Math.abs)
Вам не нужен вызов Number, который требует разрешения глобального объекта и т. д. Unary + выполняет достаточную работу.
Вместо того, чтобы делать свой собственный пресс, вы можете использовать встроенные браузеры: var abs = Math.abs; предупреждение (абс (-1));
Я бы посоветовал выбрать метод, который более четко показывает ваше намерение, а не беспокоиться о производительности. В этом случае выигрыш в производительности от умножения на -1, вероятно, минимален.
Когда вы используете Math.abs(), совершенно очевидно, что вам нужно положительное значение. Когда вы используете * -1, это не ясно и требует дополнительных исследований, чтобы определить, всегда ли входное значение отрицательное.
+1. Первое правило оптимизации: "не делай этого". Второе правило оптимизации (только знатоки!): «не делай этого ... пока». :-)
Сначала я хотел не согласиться с вашим изложенным в книге ответом, чтобы избежать преждевременных оптимизаций, поскольку в JS было отсутствуют оптимизации компилятора из-за того, что он является интерпретированный. Было разумно использовать эти маленькие уловки для увеличения производительности, если это действительно имело значение. Однако современные браузеры делать (jit-) компилировать JS делают такие оптимизации все более и более устаревшими.
Обновлено в августе 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 года назад, -a был самым быстрым, но теперь Math.abs (x) быстрее в Firefox! В Chrome abs(a) и -a показали одинаковое время, и разница всего в 3 мс с самым медленным методом, когда я тестировал его с 10 000 000 номеров.
Моя рекомендация: используйте Math.abs (а). Если вы находитесь в замкнутом цикле и при профилировании выяснилось, что он слишком медленный, вы можете использовать локальную ссылку на функцию 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;
Просто операция *-1, вероятно, быстрее, но имейте в виду, что конечный результат отличается из результата для math.abs ().
math.abs(-5) и math.abs(5) возвращают 5.
-5 * -1 также возвращает 5.
5 * -1 возвращает -5.
Поэтому, если вы не уверены, что число отрицательное, вам придется провести несколько тестов, на которые уйдет больше времени. Можно также использовать math.abs ().
Но на самом деле, если разница в производительности между abs () и * -1 имеет значение в вашем JS, у вас, вероятно, есть более серьезные проблемы.
Вопрос стиля: зачем использовать a * -1 вместо -a?
Кроме того, я согласен, что вам следует использовать abs(), если вы заранее не знаете знак числа. Меня бы не волновала скорость, а читабельность.
Фактически, может быть быстрее использовать -x, а не x * -1.