Что быстрее: Math.abs (значение) или значение * -1?

Довольно просто, но я просто хочу знать, что быстрее.

Я думаю, что простое умножение числа на -1 намного быстрее, чем вызов предопределенного метода, при условии, что вы уверены, что значение отрицательное.

Но в таком случае для чего нужна функция abs()? Это просто для того, чтобы возвращаемое значение всегда было положительным, независимо от знака значения?

Фактически, может быть быстрее использовать -x, а не x * -1.

Prestaul 14.01.2009 07:55

Быстрый ответ для людей будущего: ни то, ни другое.

Tortoise 05.11.2012 07:24

..если вы не используете специальную функцию: jsperf.com/math-abs-vs-custom-abs-function, где Math.abs() значительно превосходит все остальное.

h2ooooooo 16.11.2012 19:16

по этому тесту: jsben.ch/#/ZJRAv .. разницы почти не должно быть.

EscapeNetscape 24.10.2016 11:23
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
41
4
31 394
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Я полагаю, это зависит от реализации, но 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.

olliej 14.01.2009 08:21

(Случайный факт: в текущих выпусках WebKit это на самом деле быстрее, чем при использовании Math.abs)

olliej 14.01.2009 08:23

Вам не нужен вызов Number, который требует разрешения глобального объекта и т. д. Unary + выполняет достаточную работу.

olliej 14.01.2009 10:30

Вместо того, чтобы делать свой собственный пресс, вы можете использовать встроенные браузеры: var abs = Math.abs; предупреждение (абс (-1));

some 14.01.2009 17:47

Я бы посоветовал выбрать метод, который более четко показывает ваше намерение, а не беспокоиться о производительности. В этом случае выигрыш в производительности от умножения на -1, вероятно, минимален.

Когда вы используете Math.abs(), совершенно очевидно, что вам нужно положительное значение. Когда вы используете * -1, это не ясно и требует дополнительных исследований, чтобы определить, всегда ли входное значение отрицательное.

+1. Первое правило оптимизации: "не делай этого". Второе правило оптимизации (только знатоки!): «не делай этого ... пока». :-)

HostileFork says dont trust SE 23.03.2014 02:22

Сначала я хотел не согласиться с вашим изложенным в книге ответом, чтобы избежать преждевременных оптимизаций, поскольку в JS было отсутствуют оптимизации компилятора из-за того, что он является интерпретированный. Было разумно использовать эти маленькие уловки для увеличения производительности, если это действительно имело значение. Однако современные браузеры делать (jit-) компилировать JS делают такие оптимизации все более и более устаревшими.

mucaho 29.07.2015 22:59
Ответ принят как подходящий

Обновлено в августе 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(), если вы заранее не знаете знак числа. Меня бы не волновала скорость, а читабельность.

Другие вопросы по теме