Javascript Math.ceil (Math.abs ()) оптимизация - PullRequest
5 голосов
/ 06 января 2011

Я использую Math.ceil( Math.abs( x ) ) внутри цикла.

Может кто-нибудь реализовать какую-либо оптимизацию для этой операции?(Побит или что?)

Добро пожаловать в тест на jsperf.com

Ответы [ 6 ]

8 голосов
/ 06 января 2011

Math.abs не упрощается в соответствии с webkit JavaScriptCore

case MathObjectImp::Abs:
result = ( arg < 0 || arg == -0) ? (-arg) : arg;

Однако ceil использует функцию ceil C

 case MathObjectImp::Ceil:
    result = ::ceil(arg);

, поэтому тестирование на JSpref http://jsperf.com/math-ceil-vs-bitwise побитнее - быстрее
тестирование @ ответ orangedog http://jsperf.com/math-ceil-vs-bitwise/2 Math.ceil быстрее

Так что я думаю, ваш лучший выбор:

var n = Math.abs(x);
var f = (n << 0),
f = f == n ? f : f + 1;
3 голосов
/ 06 января 2011

x < 0 ? Math.ceil(-x) : Math.ceil(x) обеспечивает 40% ускорение в Firefox 3.6 (небольшая разница в других), оставаясь при этом относительно читабельным.

Вот страница jsPerf .Игнорировать метку "некоторые побитовые операторы";Выражение выше не использует любое.

2 голосов
/ 06 января 2011

Javascript не является компилируемым языком, подобным C, поэтому побитовые операции, которые могут творить чудеса на таких языках, не так хороши в JS, потому что числа хранятся как 64-битные числа с плавающей запятой. Взгляните на этот ТАК .

Даже в этом случае то, что вы пишете в JS, будет каким-то образом преобразовано в нативный код базовым браузером и может быть быстрее или медленнее, в зависимости от реализации.

Поскольку встроены Math.ceil и Math.abs; Я предполагаю, что они сильно оптимизированы, поэтому я сомневаюсь, что вы сможете повысить производительность, выполнив некоторые собственные хитрости.

Итог: три вещи стоят на вашем пути, чтобы сделать это быстрее:

  1. представление чисел в JS
  2. тот факт, что это интерпретируемый язык
  3. используемые вами функции являются "нативными", поэтому они должны быть достаточно быстрыми
1 голос
/ 06 января 2011

Вот еще один, который не нужно искать:

((x >= 0 ? x : -x) + 0.5) >> 0
1 голос
/ 06 января 2011

parseInt(Math.abs(x)) + 1 быстрее примерно на 30% в Firefox в соответствии с jsperf

Поскольку аргумент всегда положительный, ветви в Math.ceil () не нужны.

0 голосов
/ 27 марта 2013

Два самых быстрых способа вычисления (обеспечивающих почти одинаковую скорость в современных браузерах):

function f (n) {
   return (~~n) + 1;
}

// or 

function f1 (n) {
   return (n | 0) + 1;
}

// some tests, ~~ operator seems to work identicaly on numbers:

( 3.3 | 0 ) === 3;   
( 3.8 | 0 ) === 3;   
( -3.3 | 0 ) === -3; 
( -3.8 | 0 ) === -3;  

в отличие от Math.floor(-3.3) == Math.floor(-3.8) == -4

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...