Текущий архив: 2003.03.03;
Скачать: CL | DM;
ВнизКак максимально увеличить скорость кода? Найти похожие ветки
← →
MAN-In-RED (2003-02-13 23:57) [0]Не для конкретного случая, а может есть какие-то общие правила?
Заранее благодарен!
← →
Jeer (2003-02-14 00:01) [1]Бустер в 3 GHz
← →
Alex Konshin (2003-02-14 00:03) [2]http://www.optimalcode.com/index.htm
← →
Jeer (2003-02-14 00:09) [3]Это слишком общее пожелание.
Нужна конкретика, это более продуктивный путь.
Для себя я давно ответ нашел:
"Алгоритмы начинают и выигрывают".
← →
Alex Konshin (2003-02-14 00:27) [4]Ты сайт-то посмотри, там есть что почитать (по крайней мере когда-то было).
← →
MAN-In-RED (2003-02-14 00:34) [5]
> Jeer © (14.02.03 00:01)
Это не выход...
> Alex Konshin © (14.02.03 00:27)
Ок, посмотрю, будет время...
Давайте рассмотрим конкретный случай:
procedure TForm1.Button1Click(Sender: TObject);
var
X,Y,
Nb :Integer;
begin
Memo1.Clear;
Memo1.Enabled := False;
Nb := 0;
ProgressBar1.Max := Image1.Width*Image1.Height;
for Y:=0 to Image1.Height do
for X:=0 to Image1.Width do
begin
Application.ProcessMessages;
ProgressBar1.Position := ProgressBar1.Position+1;
if Image1.Canvas.Pixels[X,Y]=clBlack then
Inc(Nb,1)
else
if Nb<>0 then
begin
Memo1.Text := Memo1.Text+IntToStr(Nb);
Nb := 0;
end;
end;
Memo1.Enabled := True;
end;
Нужно выжать все соки из этого алгоритма...
← →
Jeer (2003-02-14 00:42) [6]Во-первых давно известно про ScanLine
Во-вторых, найди FastBMP - там через указатели..
G. Alex Cowie <gfody@jps.net>
www.jps.net/gfody
← →
Jeer (2003-02-14 00:48) [7]В третьих
работа со строками в Pascal - никуда.
Оптимизируй:
загоняй Nb в массив int
а затем уж разбирай в текст и не через IntToStr.
Никто тебе не мешает провести тестовые испытания функций конвертации.
s:=s+ss - это тоже плохо
← →
kaif (2003-02-14 01:07) [8]Нужно не максимально увеличить скорость кода, а разумно увеличить. Например, увеличение скорости на 1% не имеет значения, если весь код выполняется за 0.1 сек и выдает список товаров на экран.
Я для себя нашел такое правило:
Всегда заранее знать, где именно в коде может произойти сильное и неоправданное замедление.
Например в приведенном выше примере я с первого взгляда понимаю в чем, собственно, прикол. Метод Canvas.Pixels[x,y] очень медленный и в документации прямо сказано о том, чтобы им не пользоваться как попало. Мне даже ненужно знать, в чем задача. Достаточно того, что такой метод вызван в двойном цикле for...
То есть нужно заранее знать узкие места реализации.
А алгоритм просто просто всегда должен быть на высоте, если есть время подумать. Это не ради скорости, а ради того, чтобы культура программирования не выветрилась и интерес к профессии не потерять окончательно в погоне за бабками...
← →
Aristarh (2003-02-14 01:33) [9]Узнаю кайфа, с его философией. Но он прав!
← →
MAN-In-RED (2003-02-14 02:11) [10]Написал новый код, уже использовал массив. Результат есть…
Этот код (сверху), выполняется примерно за 99250 мс.
Новый код, только что написал, за 820.
No comments.
← →
Asker (2003-02-14 02:12) [11]стоит попробовать вынести Application.ProcessMessages; на уровень вверх, вполне вероятно, что будет работать быстрее. Чаще всего не требуется вызывать его так часто
← →
Думкин (2003-02-14 05:32) [12]
> Asker (14.02.03 02:12)
Вот тут в точку. Хотя и Pixels тоже в точку, я недавно с этим бодался - массив то маленький(1 метр), но прога его раскуручивала ... no comments
← →
Anatoly Podgoretsky (2003-02-14 07:56) [13]procedure TForm1.Button1Click(Sender: TObject);
var
X,Y,
Nb :Integer;
begin
Memo1.Clear;
Memo1.Enabled := False;
Nb := 0;
ProgressBar1.Max := Image1.Width*Image1.Height;
for Y:=0 to Image1.Height do
for X:=0 to Image1.Width do
begin
Application.ProcessMessages;
ProgressBar1.Position := ProgressBar1.Position+1;
end;
end;
Замерь сначала это
← →
Юрий Зотов (2003-02-14 09:47) [14]Простая замена в цикле Memo1.Text на локальную строку S уже резко увеличит скорость. А ПОСЛЕ выхода из цикла пишем S в Memo1.Text, всего один раз.
← →
RV (2003-02-14 09:53) [15]http://www.podgoretsky.com
Использование ассемблера в Дельфи
интересно и просто, можно поизвращаться с примерами
← →
Ketmar (2003-02-14 10:40) [16]кстати, какой глубокомысленный код. а главное -- какой бесполезный. получить кучу цифирок можно и при помощи обыкновенного Random"а. быстрее будет.
Satanas Nobiscum! 14-Feb-XXXVIII A.S.
← →
Думкин (2003-02-14 10:45) [17]
> Ketmar © (14.02.03 10:40)
Верное замечание, но тут недавно война по поводу Рэндома была, поэтому и тут holy war получится может. Скажут, что ... а впрочем пусть сами.
← →
Radionov Alexey (2003-02-14 11:48) [18]>MAN-In-RED © (13.02.03 23:57)
Procedure TForm1.Button1Click(Sender: TObject);
Var
X, Y, Nb, W: Integer;
Bmp: TBitMap;
P: PByteArray;
SL: TStringList;
Begin
Screen.Cursor := crHourGlass;
Memo1.Clear;
Nb := 0;
Bmp := Image1.Picture.Bitmap;
Bmp.PixelFormat := pf24bit; // Если картинка 24-битная. В другом формате - менятеся способ доступа к ScanLine
W := Bmp.Width;
With progressBar1 Do
Begin
Max := Bmp.Height - 1;
Min := 0;
End;
SL := TStringList.Create;
Try
For Y := 0 To Bmp.Height - 1 Do
Begin
P := Bmp.ScanLine[y];
For x := 0 To W - 1 Do
If Integer((@P[3 * x])^) And $00FFFFFF = 0 Then
inc(Nb)
Else
If Nb <> 0 Then
SL.add(IntToStr(Nb));
If y Mod 10 = 0 Then
Begin
ProgressBar1.Position := y;
Application.ProcessMessages;
End;
End;
Memo1.Text := SL.Text;
Finally
Sl.Free;
Screen.Cursor := crDefault;
ProgressBar1.Position := 0;
End;
Refresh;
End;
Но только нахрена в Memo? Имхо изврат еще тот...
← →
Radionov Alexey (2003-02-14 11:51) [19]Сорри, нужно
If Integer((@P[3 * x])^) And $00FFFFFF = 0 Then
заменить на
If Integer((@P[3 * x])^) And $FFFFFF = 0 Then
← →
han_malign (2003-02-14 12:04) [20]TBitmap.Dormant;
увеличить шаг Progress-а(см. Radionov Alexey © (14.02.03 11:48));
Больше всего времени тратится именно на отображение(в несколько раз больше чем на математику). Если изображение меньше нескольких десятков мегабайт, ProgressBar - не имеет смысла, т.к. он будет отображать процесс отображения себя...
Кстати:
var P: pointer;
........................
P := Bmp.ScanLine[y];
For x := 0 To W - 1 Do begin
If Integer(P^) And $00FFFFFF = 0 Then
inc(Nb)
Else
If Nb <> 0 Then
SL.add(IntToStr(Nb));
inc(P,3);
end;
- классический C-шный подход...
← →
Anatoly Podgoretsky (2003-02-14 12:04) [21]MAN-In-RED © (14.02.03 00:34)
Так ты замерил это Anatoly Podgoretsky © (14.02.03 07:56)
или нет?
← →
Radionov Alexey (2003-02-14 12:10) [22]>han_malign © (14.02.03 12:04)
токмо
If Integer(P^) And $00FFFFFF = 0 Then
заменить на
If Integer(P^) And $FFFFFF = 0 Then
← →
han_malign (2003-02-14 12:35) [23]Radionov Alexey © (14.02.03 12:10)
- абсолютно ни какой разницы, хоть $0000000000FFFFFF
← →
Radionov Alexey (2003-02-14 12:45) [24]>han_malign © (14.02.03 12:35)
Блин, вот я тормознул! 8-()
Конечно же на If Integer(P^) And $FFFFFF00 = 0 Then
← →
ZeroDivide (2003-02-14 12:45) [25]Если надо выжимать соки тогда только асм. И не надо даже пытаться что то сделать hi-level. Самый оптимальный алгоритм переведенный в асм (и слегка там поправленый) будет работать на 10% быстрее что для соковарении очень важно.
← →
Radionov Alexey (2003-02-14 12:52) [26]>ZeroDivide © (14.02.03 12:45)
>"И не надо даже пытаться что то сделать hi-level"
Ну да, конечно :)
Лабуда, она лабудой и останется, хоть на ASMе ее напиши, хоть сразу в машинных кодах. ИМХО "соковарение" - прежде всего хорошая математическая проработка/оптимизация алгоритма, а уж потом тесные места на asme ваять.
← →
han_malign (2003-02-14 12:55) [27]>Radionov Alexey © (14.02.03 12:45)
>>han_malign © (14.02.03 12:35)
>Блин, вот я тормознул! 8-()
>Конечно же на If Integer(P^) And $FFFFFF00 = 0 Then
- а вот это тебя уже глючит - нас интересуют как раз младшие разряды (TColor($FFFFFF00)==>$FFFF00), все-таки Little endian...
← →
Radionov Alexey (2003-02-14 13:25) [28]>han_malign © (14.02.03 12:55)
Что поделать, сегодня я с дуба рухнул. Значит первоначальный вариант был правильным
← →
iZEN (2003-02-15 10:56) [29]Делать рефакторинг кода.
Страницы: 1 вся ветка
Текущий архив: 2003.03.03;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.008 c