Который является самым быстрым способом получить абсолютное значение числа

Расширяя комментарий @ ceejayoz, более простым способом также может быть использование глобальной вспомогательной функции.

Например, у вас может быть глобальная функция send_email(), которая будет отправлять / ставить электронную почту в очередь в зависимости от конфигурации вашего приложения.

if ( ! function_exists('send_email')) {
    /**
    * Sends or queues email
    *
    * @return mixed
    */
    function send_email($mailer, $content)
    {
        return config('app.queueemail')
            ? $mailer->queue($content)
            : $mailer->send($content); 
    }
}

Чтобы использовать его, вы должны сделать:

send_email($mailer, $content); 
40
задан chema989 20 July 2016 в 17:10
поделиться

9 ответов

Условные выражения медленнее, чем простые арифметические операции, но очень, намного быстрее, чем что-то столь же глупое как вычисление квадратного корня.

Эмпирические правила с моих дней блока:

  • Целое число или поразрядный op: 1 цикл
  • add/sub/mul С плавающей точкой: 4 цикла
  • отделение С плавающей точкой: ~30 циклов
  • возведение в степень С плавающей точкой: ~200 циклов
  • sqrt С плавающей точкой: ~60 циклов в зависимости от реализации
  • Условный переход: в среднем. 10 циклов, лучше, если хорошо предсказано, намного хуже, если mispredicted
62
ответ дан Violet Giraffe 27 November 2019 в 00:58
поделиться

Вы используете 8 086 блоков?;-)

                ; abs value of AX
   cwd          ; replicate the high bit into DX
   xor  ax, dx  ; take 1's complement if negative; no change if positive
   sub  ax, dx  ; AX is 2's complement if it was negative The standard
                : absolute value method works on any register but is much
                ; slower:

   or   bx, bx  ; see if number is negative
   jge  notneg  ; if it is negative...
   neg  bx      ; ...make it positive
notneg:         ; jump to here if positive

(скандально украденный )

1
ответ дан Mark Maxham 27 November 2019 в 00:58
поделиться

Операция по модулю используется для нахождения остатка, Вы имеете в виду абсолютное значение. Я изменил вопрос, потому что это должно быть если! на месте продажи (x) тогда x = x*-1. (не отсутствовал)

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

, Если Вы хотите внимательно наблюдать за эффективностью, в то время как Вы кодируете, необходимо только волноваться о большой-O сложности алгоритмов.

, Если операторы очень эффективны, это оценивает любое выражение и затем просто изменяется счетчик команд на основе того условия. Счетчик команд хранит адрес следующей инструкции, которая будет выполняться.

Mulitplication-1 и проверяющий, больше ли значение, чем 0, оба могут быть уменьшены до единственной инструкции по сборке.

Нахождение корня числа и возведения в квадрат того числа сначала является определенно большим количеством операций, чем если с отрицанием.

2
ответ дан Brian R. Bondy 27 November 2019 в 00:58
поделиться

Время, потраченное, чтобы сделать квадратный корень, намного больше, чем время, потраченное, чтобы сделать условное выражение. Если Вам преподавали избежать условных выражений, потому что они являются медленными, то Вы были дезинформированы. Они намного медленнее, чем тривиальные операции как добавление или вычитание целых чисел или смещение бита - который является, почему разворачивание циклов может иметь выгоду, только если Вы делаете такие тривиальные операции. Но в главной схеме вещей условные выражения являются хорошими и быстрыми, не плохо и медленными. Чтобы сделать что-то столь сложное, как вызывают функцию или вычисляют квадратный корень для предотвращения условного оператора, является сумасшедшим.

кроме того, вместо (x = x *-1), почему бы не (x = 0 - x)? Возможно, компилятор оптимизирует их то же, но разве второй не более прост так или иначе?

1
ответ дан thomasrutter 27 November 2019 в 00:58
поделиться

if вариант почти наверняка будет ослепляюще быстро по сравнению с квадратным корнем, так как он обычно переводит в команду условного перехода на уровне машинного кода (после оценки выражения, которое может быть сложным, но не в этом случае, так как это - простая проверка меньше чем на 0).

Пущение квадратного корня числа, вероятно, будет намного медленнее (Метод ньютона, например, использовал бы многие многие if операторы на уровне машинного кода).

вероятный источник беспорядка является тем, что if неизменно ведущий к изменению указателя команд непоследовательным способом. Это может замедлить процессоры, которые выбирают инструкции с упреждением в конвейер, так как они должны повторно заполнить конвейер, когда адрес неожиданно изменяется.

Однако стоимость этого была бы крохотной по сравнению с выполнением операции квадратного корня в противоположность простому проверять-и-инвертировать.

4
ответ дан paxdiablo 27 November 2019 в 00:58
поделиться

Вычисление квадратного корня является, вероятно, одной из худших вещей, которые Вы могли сделать, потому что это действительно медленно. Обычно существует библиотечная функция для того, чтобы сделать это; что-то как Математика. Брюшной пресс (). Умножение с-1 является также ненужным; просто возвратите-x. Таким образом, хорошее решение было бы следующим.

(x >= 0) ? x : -x

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

11
ответ дан Daniel Brückner 27 November 2019 в 00:58
поделиться

Тьфу, Ваши учителя на самом деле сказали Вам это? Правило, за которым следует большинство людей, состоит в том, чтобы сделать Ваш код читаемым первый, и затем настроить любые проблемы производительности после того, как они, как доказывают, на самом деле являются проблемами. 99,999% времени Вы никогда не собираетесь видеть проблему производительности, потому что Вы использовали слишком многих если операторы. Knuth заявил это лучше всего , "преждевременная оптимизация является корнем всего зла".

26
ответ дан Ed S. 27 November 2019 в 00:58
поделиться

Для списка отрицательных чисел:

, если у Вас есть нуль, сохраненный в памяти, просто используйте 0 - x, где x отрицательное число.

Или если у Вас нет нуля сохраненным в памяти:

x-x-x, где x отрицательное число.

Или, со скобками для ясности:

(x) - (x) - (x) => (-n) - (-n) - (-n), где x = -n

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

0
ответ дан 27 November 2019 в 00:58
поделиться

Существует большой трюк для расчета абсолютного значения целого числа в комплекте 2S, не используя заявление, если. Теория идет, если значение негативно, вы хотите переключить биты и добавить один, в противном случае вы хотите пройти биты, как есть. XOR 1 случается с переключением A и HOR 0 случается, чтобы оставить неповрежденный. Таким образом, вы хотите сделать что-то вроде этого:

  uint32_t temp = value >> 31;     // make a mask of the sign bit
  value ^= temp;                   // toggle the bits if value is negative
  value += temp & 1;               // add one if value was negative

в принципе, вы можете сделать это всего за три инструкции по сборке (без ветки). И вы хотели бы подумать, что функция ABS (), которую вы получаете с Math.h, делает это оптимально.

Нет ветвей == лучшая производительность. Наоборот от ответа @ Paxdiablo, это действительно имеет значение в глубоких трубопроводах, где больше ветвей у вас есть в вашем коде, тем более вероятно, что вы должны иметь предиктор вашего филиала, вытесните это неправильно и должны откатывать и т. Д. Если вы избежите разветвления, где Возможно, все будет двигаться вперед на полном газе в вашем ядре :).

78
ответ дан 27 November 2019 в 00:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: