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

Что быстрее? Сравнение или назначение?

Я делаю немного кодирования, где мне нужно написать такой код:

if( array[i]==false )
    array[i]=true;

Интересно, нужно ли его переписывать как

array[i]=true;

Возникает вопрос: сравнения быстрее, чем назначения?

Как насчет отличий от языка к языку? (контраст между java и cpp, например.)

ПРИМЕЧАНИЕ. Я слышал, что "преждевременная оптимизация - это корень всего зла". Я не думаю, что это применимо здесь:)

4b9b3361

Ответ 1

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

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

Ответ 2

Это не просто преждевременная оптимизация, это микро-оптимизация, что является нерелевантным отвлечением.

Предполагая, что ваш массив имеет тип boolean, тогда ваше сравнение не нужно, что является единственным соответствующим наблюдением.

Ответ 3

Изменить: я написал script в PHP. Я просто заметил, что в нем была вопиющая ошибка, означающая, что наилучшее время исполнения вычислялось неправильно (страшно, что никто не заметил!)

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

Вывод:

  • в 0.0119960308075 секунд
  • наихудшее сравнение случаев в 0.0188510417938 секунд
  • лучший пример сравнения в 0.0116770267487 секунд

код:

<?php
$arr = array();

$mtime = explode(" ", microtime());
$starttime = $mtime[1] + $mtime[0];

reset_arr($arr);

for ($i=0;$i<10000;$i++)
    $arr[i] = true;


$mtime = explode(" ", microtime());
$firsttime = $mtime[1] + $mtime[0];
$totaltime = ($firsttime - $starttime);
echo "assignment in ".$totaltime." seconds<br />"; 

reset_arr($arr);

for ($i=0;$i<10000;$i++)
    if ($arr[i])
        $arr[i] = true;

$mtime = explode(" ", microtime());
$secondtime = $mtime[1] + $mtime[0];
$totaltime = ($secondtime - $firsttime);
echo "worst case comparison in ".$totaltime." seconds<br />"; 

reset_arr($arr);

for ($i=0;$i<10000;$i++)
    if (!$arr[i])
        $arr[i] = false;

$mtime = explode(" ", microtime());
$thirdtime = $mtime[1] + $mtime[0];
$totaltime = ($thirdtime - $secondtime);
echo "best case comparison in ".$totaltime." seconds<br />"; 

function reset_arr($arr) {
    for ($i=0;$i<10000;$i++)
        $arr[$i] = false;
}

Ответ 4

Зависит от языка. Однако петлевые массивы могут быть дорогостоящими. Если массив находится в последовательной памяти, самым быстрым является запись 1 бита (255) по всему массиву с помощью memcpy, предполагая, что ваш язык/компилятор может это сделать.

Таким образом, выполнение 0 reads-1 write total, отсутствие чтения/записи переменной цикла/массива цикла (2 чтения /2 записи каждого цикла) несколько сотен раз.

Ответ 5

Я считаю, что если утверждения сравнения и присваивания являются как атомарными (т.е. одна инструкция процессора), а цикл выполняется n раз, то в худшем случае сравнение потребует n + 1 (сравнение на каждой итерации плюс установка назначения) в то время как постоянная настройка bool потребует n исполнений. Поэтому второй эффективнее.

Ответ 6

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

Ответ 7

Можете попробовать:

if(!array[i])
    array[i]=true;

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

Ответ 8

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

Ответ 9

Как отмечали другие, это микро-оптимизация.

(В политике или журналистике это известно как пупок, -)

Является ли программа достаточно большой, чтобы иметь более двух уровней вызовов функции/метода/подпрограммы?

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

В предположении, что вы удалили те (что мало кто делает), тогда непременно запустите его 10 ^ 9 раз под секундомером и посмотрите, быстрее.

Ответ 10

Если вы просто хотите перевернуть значения, выполните следующие действия:

array[i] = !array[i];

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

Если вы объявляете массив элементов 1000000 из сравнения true, false, true, false, медленнее. (var b =! b) по существу выполняет проверку дважды вместо одного

Ответ 11

Почему бы вам даже написать первую версию? Какая польза от проверки, чтобы убедиться, что что-то ложно, прежде чем установить его true. Если вы всегда установите его true, тогда всегда установите его true.

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

Ответ 12

Я помню, что в одной книге об ассемблере автор утверждал, что, если это возможно, следует избегать, если это возможно. Это намного медленнее, если условие ложно, и выполнение должно перейти к другой линии, что значительно замедляет производительность. Кроме того, поскольку программы выполняются в машинный код, я думаю, что "if" медленнее на каждом (скомпилированном) языке, если его условие не истинно почти все время.