![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
XOR для массива
MikeZ © (2006-06-04 16:30:00)Всем день добрый!
Надо сделать XOR для чисел, являющихся элементами массива.
Сейчас делаю a[i] xor b[i], перебирая так весь массив.
Есть ли какой-нибудь способ делать это по-красивее и, главное, побыстрее.
MBo (2006-06-05 14:52:00) [41]>Pavia © (05.06.06 14:47) [25]
>Бред, счетчик после цикла должен быть ровно таким каким его задал программер
По стандарту языка, переменная-счетчик цикла не определена после окончания цикла.
Pavia (2006-06-05 14:47:00) [42]
> Использование счетчика цикла за самим циклом... Никогда
> так больше не делай. Это чревато ошибками, если за оптимизацую
> цикла вдруг возьмется компилятор. Например, такой код является
> уже некорректным, хотя по существу является полным аналогом
> твоего кода:
Бред, счетчик после цикла должен быть ровно таким каким его задал программер, а не оптимизатор. Иначе компилятор на свалку.
Дело в том что компилятор не умеет хорошо оптимизировать
Inc(wA);
Inc(wB);
Здесь идет чтение из памяти. прибавление 1 и запись обратно в память.
Сдвиг и сложение выполняется одинаково. Другое дело что мой код оптимизатор оптимизирует хорошо. Обращение к памяти происходит только для считывания данных и записи результата. Сдвиг уже предусмотрен в процессоре и не занимает процессорного времени.
Loginov Dmitry (2006-06-05 14:41:00) [43]Повторюсь:
При индексированном способе доступа к элементам массива используется И сдвиг И сложение.
tesseract (2006-06-05 13:34:00) [44]
> В моем коде в теле цикла было все-таки 2 сложения...
Да но скорость у сдвига в разы больше, чем у сложения.
Профайлер врать не может.
Loginov Dmitry (2006-06-05 13:22:00) [45]В моем коде в теле цикла было все-таки 2 сложения...
tesseract (2006-06-05 12:48:00) [46]
> А какие там затраты?
Сорри код не смотрел.
While (J<=D-1)do begin
ptMain^:=ptMain^ xor ptKey^;
Inc (ptMain);
Inc (ptKey);
Inc (J);
end;
насколько я вижу здесь ТРИ сложения. конечно выполняться они могут и за такт, но сдвиг таки быстрее.
Loginov Dmitry (2006-06-05 12:43:00) [47]tesseract © (05.06.06 12:40) [19]
А затраты на доп операции с памятью ?
А какие там затраты?
tesseract (2006-06-05 12:40:00) [48]
> Не, с какой стати "индексированный доступ побыстрее работает,
> чем разадресация с инкрементом"?При индексированном доступе
> внутри цикла выполняются операции сдвига и сложения.Во втором
> случает внутри цикла выполняется только операция сложения
> - операции сдвига нет, так что скорость должна (по идее)
> увеличиваться.
А затраты на доп операции с памятью ? Сдвиг по моему не слишком много времени занимает.
Loginov Dmitry (2006-06-05 12:25:00) [49]Не, с какой стати "индексированный доступ побыстрее работает, чем разадресация с инкрементом"?
При индексированном доступе внутри цикла выполняются операции сдвига и сложения.
Во втором случает внутри цикла выполняется только операция сложения - операции сдвига нет, так что скорость должна (по идее) увеличиваться.
tesseract (2006-06-05 12:16:00) [50]насчёт скорости посмотрите pascal-реализацию system.move.
Там вот такое :
procedure Move( const Source; var Dest; count : Integer );
{$IFDEF PUREPASCAL}
var
S, D: PChar;
I: Integer;
begin
S := PChar(@Source);
D := PChar(@Dest);
if S = D then Exit;
if Cardinal(D) > Cardinal(S) then
for I := count-1 downto 0 do
D[I] := S[I]
else
for I := 0 to count-1 do
D[I] := S[I];
end;
{$ELSE}
MBo (2006-06-05 11:59:00) [51]>han_malign © (05.06.06 10:58) [13]
Поясни, ведь вопрос этот неоднозначен.
Loginov Dmitry (2006-06-05 11:37:00) [52]han_malign © (05.06.06 10:58) [13]
не ребята - индексированный доступ побыстрее работает, чем разадресация с инкрементом
Это бред!
Rial (2006-06-05 11:04:00) [53]
> Loginov Dmitry © (05.06.06 10:30) [12]
Извиняюсь, действительно нехорошо получилось ...
han_malign (2006-06-05 10:58:00) [54]
> хотя по существу является полным аналогом твоего кода
> wA^ :=wA^ xor wB^;
> Inc(wA);
> Inc(wB);
- не ребята - индексированный доступ побыстрее работает, чем разадресация с инкрементом, это нам еще в школе вдалбливали, на 80286-х...
Loginov Dmitry (2006-06-05 10:30:00) [55]Rial © (05.06.06 0:51) [11]
Будь внимательнее, когда цитируешь посты, а то могут и обидеться!
Rial (2006-06-05 00:51:00) [56]Loginov Dmitry © (05.06.06 00:15) [10]
Использование счетчика цикла за самим циклом...
не у меишь
по байтно
медленнее чем
оброщений к памити
понил
невижу
ошибка на ошибка
Сейчас проверил на шел ошибку у себя i пропустил.
Я тоже могу придраться, но просили побайтно...
Мало ли, вдруг в этом вся суть ...
А так то можно и с Int64.
Loginov Dmitry (2006-06-05 00:15:00) [57]Pavia © (04.06.06 23:04) [9]
for i:=0 to size div 4-1 do
a[i]:=a[i] xor b[i];
for i:=i*4 to i*4+size mod 4 -1 do
PAbyte(a)[i]:=PAbyte(a)[i] xor PAbyte(b)[i];
Использование счетчика цикла за самим циклом... Никогда так больше не делай. Это чревато ошибками, если за оптимизацую цикла вдруг возьмется компилятор. Например, такой код является уже некорректным, хотя по существу является полным аналогом твоего кода:
procedure pp_(a,b:PADWord; size:integer);
var i, k:integer;
wA, wB: ^DWORD;
begin
wA := @a[0];
wB := @b[0];
for i:=0 to size div 4-1 do
begin
wA^ :=wA^ xor wB^;
Inc(wA);
Inc(wB);
end;
for i:=i*4 to i*4+size mod 4 -1 do
PAbyte(a)[i]:=PAbyte(a)[i] xor PAbyte(b)[i];
end;
Pavia (2006-06-04 23:04:00) [58]Что-то у меня сегодня ошибка на ошибка.
procedure pp2(a,b:PADWord; size:integer);
var i:integer;
begin
for i:=0 to size div 4-1 do
a[i]:=a[i] xor b[i];
for i:=i*4 to i*4+size mod 4 -1 do
PAbyte(a)[i]:=PAbyte(a)[i] xor PAbyte(b)[i];
end;
Пс модератору сотрите предыдущий пост.
Pavia (2006-06-04 23:02:00) [59]Блин. Сейчас проверил на шел ошибку у себя i пропустил.
procedure pp2(a,b:PADWord; size:integer); // Мой вариант 4Байта за раз.
var i:integer;
begin
for i:=0 to size div 4-1 do
a[i]:=a[i] xor b[i];
for i:=i to i+size mod 4 -1 do
PAbyte(a)[i]:=PAbyte(a)[i] xor PAbyte(b)[i];
end;
Pavia (2006-06-04 22:43:00) [60]Rial не у меишь ты писать. Проверил я твой код. Он медленнее чем если делать по байтно.
2735 - твой код
1781 - по байтно
469 - мой код
В твоем коде много оброщений к памити.
И еще я так понил A,B одного размера.
type
TAbyte=array [0..0] of byte;
PAbyte=^TAbyte;
TADWord=array [0..0] of DWord;
PADWord=^TADWord;
procedure pp1(a,b:PAbyte; size:integer); // По байтно
var i:integer;
begin
for i:=0 to size-1 do
a[i]:=a[i] xor b[i];
end;
procedure pp2(a,b:PADWord; size:integer); // Мой вариант 4Байта за раз.
var i:integer;
begin
for i:=0 to size div 4-1 do
a[i]:=a[i] xor b[i];
for i:=i to size mod 4 -1 do
PAbyte(a)[i]:=PAbyte(a)[i] xor PAbyte(b)[i];
end;
На асм переписать можно, но смысла невижу.