2013-05-14 11 views
1

Я читал на сайте, что с помощью xor swaps быстро, потому что он не использует временную переменную. Вот пример:Почему люди не используют обмены xor?

#include <stdio.h> 

int main(void) 
{   
    int a=234,b=789; 
    b=b^a; 
    a=b^a; 
    b=b^a; 
    printf("a=%d,b=%d",a,b); 
    return 0; 
} 

Почему люди не используют эту технику в реальной жизни? Это просто плохой стиль? Что-то не так четко определено? Это оптимизация, которую мой компилятор может производить из более чистого кода, автоматически?

+2

Я сомневаюсь, что есть много доказательств того, что это быстрее, очень часто (если вообще). –

+0

http://stackoverflow.com/faq#dontask – xaxxon

+1

@xaxxon Какую часть этой страницы вы пытаетесь мне предупредить? – Sebivor

ответ

17
  1. Поскольку читаемость является предпочтительной по сравнению с производительностью.

  2. Потому что tmp = a; a = b; b = tmp; не , что медленный.

  3. Потому что компилятор все равно оптимизирует его.

  4. Потому что он работает только для целых чисел. Что делать, если вы хотите обменять числа с плавающей запятой? Строки? Пользовательские объекты? и т. д.

+0

Это просто покрывает его. Чтобы развернуть это: компилятор будет лучше выполнять оптимизацию подкачки в пункте 2, чем замену xor; Часто это будет переведено только на одну команду (или иногда на нуль, потому что вместо инструкций заказа могут быть заменены), в то время как обмен xor по-прежнему равен трем. Кроме того, существуют слабо определенные аспекты обмена xor; Они могут создавать неверные результаты или представления ловушек, особенно когда используются отрицательные числа ... Не говоря уже о том, что сосредоточение на этой * оптимизации * глупо; Вероятно, будут гораздо более значимые, идентифицированные профилированием. – Sebivor

+0

Он работает не только для целых чисел. Он не имеет понятия данных, которые вы обмениваете, если вы не скажете, что все двоичные данные являются целыми числами. XOR swap trick работает для любых двух вещей одинакового размера. Например, это отлично подходит для замены чисел с плавающей запятой. – xaxxon

+0

@undefinedbehaviour Для этого [этот вопрос и ответ] (http://stackoverflow.com/questions/11644362/bitwise-operation-on-sign-integer) является хорошим чтением. – 2013-05-14 05:29:02

1

Коэффициент усиления производительности, как правило, настолько мал, что стоимость «понятного кода» выше, чем полученная скорость.

+0

Достигнутая производительность фактически не существует. Компилятор позаботится обо всем этом для вас - на самом деле чем более «нормальный» ваш код работает, тем лучше работа, которую может сделать компилятор. И компилятор лучше оптимизирует вашу платформу, чем вы. – xaxxon

+1

Компилятор лучше оптимизирует, если вы не знаете сборки. – Devolus

+0

Несмотря на это, скорее всего, компилятор будет бить вас чаще, чем нет. Эти вещи чертовски умны. – tangrs

2
  1. Пока нет явной временной переменной, результаты фактически сохраняются в неявной временной переменной перед записью в регистр.

  2. С заменой xor вам необходимо убедиться, что переменные, которые меняются местами, не одинаковы. Иначе как должны быть оценены на 0.

+0

За # 2: хорошая точка. Для №1: Откуда вы знаете? Вы посмотрели код, созданный каждым компилятором в мире? – 2013-05-14 05:12:49

+0

Предполагается, что 'a^a' должен быть зависимым от компилятора? – devnull

+0

Нет. Посмотрите на порядковые номера в моем комментарии - они не # 1 и # 2, а # 2 и # 1. – 2013-05-14 05:20:25

5

Все ответы уже там считают это всего лишь дополни-

-> если оба значения идет по той же памяти адреса результат будет нулевым

- > компиляторы могут оптимизировать временную переменную в наивном свопе

-> современные процессоры стремятся выполнять инструкции параллельно через конвейеры команд , но с использованием технологии XOR значительно медленнее, чем использование временной переменной Уэппинге поскольку каждая операция зависит от результата предыдущего

-> х + Y может пойти на целочисленное переполнение