Подтвердить что ты не робот

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

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

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

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

4b9b3361

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