Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Оптимизация кода


Страницы:   1 2 3 4 5 6 7 8 9 10 11

Вова ©   (2013-06-25 20:17:00) 

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


function almostEqual(a, b: byte): Boolean;
begin
 if ABS(a - b) < 10 then
   result := true
 else
   result := false;
end;

Function ConvertColorToRGBColorMap(color: LongInt; ColSel: String = 'None')
 : TColorWithName;
var
 RGBV: trgbcolor;
begin

 RGBV.red := color;
 RGBV.green := color shr 8;
 RGBV.blue := color shr 16;

 with RGBV do

   if almostEqual(red, green) and almostEqual(red, blue) and
     almostEqual(blue, green) then // тогда это серый или черный или белый
   begin
     if almostEqual(red, 255) then // белый
     begin
       result.color := RGB(255, 255, 255);
       result.Name := 'White';
     end
     else if red > 120 then
     begin
       result.color := RGB(190, 190, 190);
       result.Name := 'LightGray';
     end
     else if (red > 92) then // темно серый
     begin
       result.color := RGB(100, 100, 100);
       result.Name := 'DarkGray';
     end
     else
     begin
       result.color := RGB(0, 0, 0);
       result.Name := 'Black';
     end // черный
   end
   else
   begin
     if (red < green) and (red < blue) and almostEqual(green, blue) and
       (blue > 130) then
     begin
       result.color := RGB(0, 0, 255);
       result.Name := 'Blue';
     end // result:= rgb(0,255,255)//голубой
     else if (green < red) and (green < blue) and almostEqual(red, blue) and
       (red > 130) then
     begin
       result.color := RGB(255, 0, 255);
       result.Name := 'Pink';
     end // розовый
     else if (blue < green) and (blue < red) and almostEqual(green, red) and
       (green > 130) then
     begin
       result.color := RGB(255, 255, 0);
       result.Name := 'Yellow';
     end // желтый
     else if (red > green) and (red > blue) and (red > 130) then
     begin
       result.color := RGB(255, 0, 0);
       result.Name := 'Red';
     end // красный
     else if (blue > green) and (blue > red) and (blue > 130) then
     begin
       result.color := RGB(0, 0, 255);
       result.Name := 'Blue';
     end // синий
     else if (green > blue) and (green > red) and (green > 130) then
     begin
       result.color := RGB(0, 255, 0);
       result.Name := 'Green';
     end // зеленый
     else
     begin
       result.color := RGB(0, 0, 0);
       result.Name := 'Black';
     end
   end;

   if not (ColSel = 'None') then
     if not (ColSel = Result.Name) then
     begin
       result.color := RGB(255, 255, 255);
       result.Name := 'White'; //Если выборка только по одному цвету, то
       //все остальные цвета переводим в белый
     end
     else
     begin
       result.color := RGB(0, 0, 0);
       result.Name := 'Black'; //Если выборка только по одному цвету, то
       //этот цвет переводим в черный
     end

end;


Sha   (2013-07-02 21:31:00) [81]

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


Rouse_   (2013-07-02 21:28:00) [82]

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


Sha   (2013-07-02 21:26:00) [83]

Саш, ну ты мысленно сделай замену как в [126].
Стал бы ты тогда ставить скобки?
Согласись, они бы только мешали.

Ну вот и мне мешают. Потому и не ставлю )


Rouse_   (2013-07-02 21:22:00) [84]

Ну я раза три перечитал сей код, дабы осмыслить :)

Оть так-же гораздо удобней:

or (((i shr 16) and $FF) div 3) shl 16


Sha   (2013-07-02 21:17:00) [85]

нормально читаю, с удовольствием:

  or читается как +
  and, shr, shl читаются как *

в чем проблема-то?
не понимаю )


Rouse_   (2013-07-02 21:13:00) [86]

Фига, Сань, у тебя конструкции:
or i shr 16 and $FF div 3 shl 16
Я понимаю, запятые там можно понапропускать, все равно читабельно будет - но зачем скобки то игнорировать на таких операциях? :)
Ни разу ж не читабельно :)


Sha   (2013-07-02 17:43:00) [87]

После 2+2*2=?не читай.
Это копипаста твоего поста


Sha   (2013-07-02 17:41:00) [88]

> Вова   (02.07.13 13:25) [115]

че-то ты притих )

i shr 24 and $F0 - ставим нулевой байт второго триплета на нулевое место и оставляем в нем только 4 старших бита в старшем нибле,

j shr 4 and $F0F - ставим старший нибл первого байта второго триплета на место младшего нибла нулевого байта,
а старший нибл второго байта второго триплета на место младшего нибла первого байта,

or-им их между собой - получаем индекс для второго триплета в нашей таблице.

проще пареной репы )




> если у shl приоритет такой же как у or то вообще какая то херня

ну с приоритетами ты уж разберись, даже неудобно как-то, ты программист или где?
2+2*2=?

or j - первых 4 байта у которых значащими остались только первые 4 бита в последнем байте, накладываются на вторые 4 байта, получается вообще непонятно что )
j shr 4 - 4 правых бита от j удаляются. получается 4 байта с пустыми 4 битами в начале, и с какой то непонятной лажей (получившейся в результате or j) в самых правых 4 битах, а потом вообще ппц объединение с 111100001111, это ж полтора байта, как оно вообще накладывается (( на 4 байта! Обнуляются первые 4 бита правого байта? сдается мне что это не так, т.к почему тогда не 0F? ( но что за хрень это тогда?

В общем, к данному моменту кода у меня в голове полная каша не позволяющая идти дальше. Напоминает школу ) "В результате тривиальных вычислений получаем....." что получаем, откуда непонятно ( и как результат 10 впустую потраченных лет.

i := ColorMap[i and $F0 or i shr 12 and $F0F]; ну это понятно, см. выше ((

p[0] := i or T shl 24; - объединение 2х абракадабр, если у shl приоритет такой же как у or то вообще какая то херня, выкинули 3 байта остался 1 Оо

Все что я нашел об этом, это надписи о том, что в интернете куча статей об этом, видимо не такая уж и куча....Дайте ссылку хоть на одну! то что '1111000' or '00001111' = '11111111' это я вроде понял, только вот это никак не помогает понять, что в этом коде написано.


Jeer   (2013-07-02 17:08:00) [89]

P.S.
Что-то это мне напомнило "Радио? Это очень просто!" Айсберга.
Кстати, на самом деле, замечательный методический прием.


Jeer   (2013-07-02 17:05:00) [90]

Приятно, когда мастера общаются in self и это правильно:)


Sha   (2013-07-02 14:39:00) [91]

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

Давай посмотрим это на простом примере. Пусть в памяти m последовательно лежат 4 байта. Надо первый из них увеличить на 1, второй умножить на 2, третий разделить на 3, четвертый оставить без изменений. Читать и писать переменную m разрешается только 1 раз.
Решение:

i:=m;
m:=(i  + 1) and $FF
  or i and $7F00 shl 1
  or i shr 16 and $FF div 3 shl 16
  or i and $FF000000;


Sha   (2013-07-02 14:10:00) [92]

Допустим в переменной i лежит цвет,
интесивность каждой составляющей в своем байте (байты 0..2).
Пусть
 i:=$00aabbcc;
Каждую из них усекаем до старших 4х битов:
 i:=i and $F0F0F0;
Получаем
 i:=$00a0b0c0;
Формируем число от 0 до 16*16*16-1 - будущий индекс цвета в таблице:
 i:=(i shr 12 and $F) + (i and $F0) + (i shr 12 and $F00);
Получаем
 i:=$00000acb;
Tот же самый результат дает
 i:=i and $F0 or i shr 12 and $F0F;


Sha   (2013-07-02 13:54:00) [93]

Зарапортовался, все с точностью до наоборот:

2. В теории, в голове и на бумаге младший байт обычно изображают справа,старший слева,


Sha   (2013-07-02 13:51:00) [94]

1. Байты в integer нумеруются с 0 до 3. Младший байт содержит содержит младшие 8 бит, т.е. остаток от деления на 256.

2. В теории, в голове и на бумаге младший байт обычно изображают слева, старший справа, (это похоже на десятичную систему, только здесь она 256-ричная).

3. В памяти машины с архитектурой IA-32 адрес integer совпадает с адресом его младшего байта, байт номер 1 хранится по адресу на 1 больше, старший байт - по адресу на 3 больше. Можно считать, что адреса растут справа налево.  

4. Команды shr и shl имеют дело с представлением 2, причем сдвиг в действительности выполняется на указанное число бит, взятое по модулю размера операнда (т.е. 32 для integer).

5. Команды and и or с integer-операндами выполняются побитно, т.е. i and 1 вернет значение младшего бита младшего байта (1 для нечетного числа, 0 для четного), a i or 1 вернет первое нечетное после i для четного i или само i для нечетного i.


Вова   (2013-07-02 13:28:00) [95]

блин (((


Вова   (2013-07-02 13:25:00) [96]

блиииин! жил же спокойно (( раз рассказали все это теперь расскажите и что это значит

старший байт тот что в конце (слева направо)?


i := p[0]; //Берем первые 4 байта в строке (BGR + 1 байт канал B от следующего пикселя)

j := p[1]; //Берем вторые 4 байта в строке

Дальше ад:
T := ColorMap[i shr 24 and $F0 or j shr 4 and $F0F];

i shr 24 - смещение вправо 3 байт, т.е. остается канал B первого пикселя? правда он теперь на месте B второго пикселя. объединяется с `11110000` опять же не понятно как, i это же 4 байта, а не 1, или он только с последним самым правым байтом или со всеми по очереди? И главное - какой в этом смысл? Блин ну это ведь что то значит ) просто так наложили какую то лажу на канал цвета, что это с цветом то делает? ) т.е. 4 последних бита обнуляются, но нафига???

or j - первых 4 байта у которых значащими остались только первые 4 бита в последнем байте, накладываются на вторые 4 байта, получается вообще непонятно что )
j shr 4 - 4 правых бита от j удаляются. получается 4 байта с пустыми 4 битами в начале, и с какой то непонятной лажей (получившейся в результате or j) в самых правых 4 битах, а потом вообще ппц объединение с 111100001111, это ж полтора байта, как оно вообще накладывается (( на 4 байта! Обнуляются первые 4 бита правого байта? сдается мне что это не так, т.к почему тогда не 0F? ( но что за хрень это тогда?

В общем, к данному моменту кода у меня в голове полная каша не позволяющая идти дальше. Напоминает школу ) "В результате тривиальных вычислений получаем....." что получаем, откуда непонятно ( и как результат 10 впустую потраченных лет.

i := ColorMap[i and $F0 or i shr 12 and $F0F]; ну это понятно, см. выше ((

p[0] := i or T shl 24; - объединение 2х абракадабр, если у shl приоритет такой же как у or то вообще какая то херня, выкинули 3 байта остался 1 Оо

Все что я нашел об этом, это надписи о том, что в интернете куча статей об этом, видимо не такая уж и куча....Дайте ссылку хоть на одну! то что '1111000' or '00001111' = '11111111' это я вроде понял, только вот это никак не помогает понять, что в этом коде написано.


Sha   (2013-07-02 08:10:00) [97]

кто ж всю лапшу сразу вываливает на клиента, так можно отпугнуть )


Sapersky   (2013-07-02 07:19:00) [98]

Ну, так все-таки разы? ))

Разы.
Мне показалось, что было утверждение вроде "выкинь купиксели и будет тебе 5-10 раз", только за счёт выкидывания. А оказывается в [57] уже была запланирована развёртка цикла с выравниванием доступа к памяти, кто бы мог подумать :)


Sha   (2013-07-01 20:12:00) [99]

> Вова   (01.07.13 18:41) [111]

Если преобразовывать цвет в цвет, то быстрее [81,85] для 24-битного цвета не получится.
А если цвет в булеан, то можно отжать еще несколько процентов.

32-битный цвет, наверно, будет в 1.2-2.0 раза быстрее в зависимости от процессора.


Вова   (2013-07-01 18:41:00) [100]

интересно, а через SetDIBits будет еще быстрее чем через сканлайн? )
может уже чтобы 2 раза потом не переделывать разобраться)


Страницы:   1 2 3 4 5 6 7 8 9 10 11

Наверх

Титульная страница Поиск, карта сайта Написать письмо