Member
Статус: Не в сети Регистрация: 14.08.2003 Откуда: Питер
Народ!!! Подскажите, как на Делфи 7 сделать индикатор хода выполнения операций в программе?
Т.е. предположим у меня программа считает очень сложныее мат. выражения и обрабатывает случайные числа.
На глаз прога считает за пару секунд (при заданиии др. пар-ров по разному). Так вот как мне зделать индикатор выполнения задачи?
Можно графически или в процентах. Без разници.
Advanced member
Статус: Не в сети Регистрация: 09.06.2003 Откуда: USSR
Halfback Создаеш форму, на нее кладеш progressbar. Также заранее просчитай как двиагрть прогресс. Тоесть от 1 до 100, это все твои операции должны быть.
Дальше допусти у тебя цикл где все это и выполняется. До начала цикла, создаеш форму
frmProgress=TFrmProgress.Create(Self);
frmProgress.ProgressBar1.Max:=тут чегото максимальное, сам должен вычислить
frmProgress.Show;
frmProgress.Update;
//начинаем цикл
for ___________
begin
//тут идут твои вычисления
frmProgress.progressBar1.StepI;
end;
frmProgress.Free;
Member
Статус: Не в сети Регистрация: 15.04.2004 Откуда: Москва
Цитата:
frmProgress=TFrmProgress.Create(Self); frmProgress.ProgressBar1.Max:=тут чегото максимальное, сам должен вычислить frmProgress.Show; frmProgress.Update; //начинаем цикл for ___________ begin //тут идут твои вычисления frmProgress.progressBar1.StepI;
Цитата:
Application.ProcessMessages; // Неплохо бы, а то прогресс бар не перерисуется...
Advanced member
Статус: Не в сети Регистрация: 09.06.2003 Откуда: USSR
Avaddon frmProgress.progressBar1.StepI;
frmProgress.progressBar1.Update;
и все Если же Application.ProcessMessages; то надо будет учитывать что все остальные элементы будут работать. Тоесть логику надо будет учесть
Member
Статус: Не в сети Регистрация: 14.08.2003 Откуда: Питер
Ray Adams А можно небольшой примерчик? Например генерация случ. чисел по какому-нибудь закону..... Ато я что-то не врубаюсь куда что писать и создавать.
Member
Статус: Не в сети Регистрация: 14.08.2003 Откуда: Питер
Ray Adams Мне вот что нужно: прога по специальному алгоритму генерирует случ.числа а потом их специальным образом сортирует. Эта операция у меня выполняется примерно 3-4 секунды. Короче - вот листинг:
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
Form2.Visible:= true;
end;
procedure TForm1.BitBtn3Click(Sender: TObject);
begin
close;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
Label Unix;
var
N,NN: integer;
i,j,v,m,k: integer;
S: integer;
R: array[1..10] of integer;
a: array[0..200000] of integer;
begin
Form1.ListBox1.Items.Clear;
N:= StrToInt(Edit1.Text);
NN:=1;
a[0]:=0;
for i:=1 to N do
begin
NN:= NN*i ;
end;
Label2.Caption:= 'Всего вариантов перестановок: ' + FloatToStr(NN);
for j:=1 to NN do
begin
Unix:
S:=0;
for v:=1 to N do
begin
R[v]:=1+Random(N);
for k:=1 to (v-1) do
begin
if R[v]=R[k] then GoTo Unix else
end;
S:= S + R[v]*Trunc(exp(v*ln(10)))
end;
a[j]:=Trunc(S/10);
for m:=1 to j-1 do
begin
if a[j]= a[m] then GoTo Unix else
end;
Если задавать N=4 или 5 то прога считает и выводит на листбокс комбинации чисел быстро. А вот если N=7 то надо ждать 3-4 секунды. Так вот мне нужен типа оценщика времени выполнения этих операций (ну например как в RAR-е мы видим ход выполнения архивации).
Но вот еще вопрос: почему когда я ставлю N=8 и более прога зависает?
И еще. Что такое прогрессбар, как вводить и для чего нужен? В доступной литературе ничего на этот счет не нашел...
Advanced member
Статус: Не в сети Регистрация: 09.06.2003 Откуда: USSR
Цитата:
Но вот еще вопрос: почему когда я ставлю N=8 и более прога зависает?
Ну ктож знает что ты там наделал Код твой, дебагер в дельфи есть, вперед А код для прогресса я тебе сейчас сделаю.
Добавлено спустя 9 минут, 38 секунд: При установки в 8 у меня ушло около 3 минут на создание списка, ничего не подвисает. Просто логику доработай для ускорения создания списке. Так как при 8 вариантов подстановок больше 40 000.
Добавлено спустя 3 минуты, 36 секунд: Короче лови исходник с доработкой небольшой. При установке в 7 тратится не больше 2 секунд. Все что ниже у меня пролетает незаметно для глаза.
Заметь что я добавил ListBox1.Items.BeginUpdate; в начале и ListBox1.Items.EndUpdate;
если у тебя очень много данных пишутся в ListBox то лучше сперва заблокировать его, сдлелать все апдейты и уж потом разблокировать. Получиш очень хороший прирост в скорости.
Member
Статус: Не в сети Регистрация: 14.08.2003 Откуда: Питер
Есть такой исходничек:
Цитата:
procedure TForm1.BitBtn2Click(Sender: TObject); Label Unix2; var N,NN: integer; i,j,v,m,k,vv: integer; S: integer; RR: integer; U: array[1..10] of shortint; R: array[1..10] of shortint; a: array[0..200000] of integer;
begin ListBox1.Items.BeginUpdate; ListBox1.Items.Clear; N:= StrToInt(Edit1.Text); //if N>=10 then ShowMessage('Неправильно введено число N'); NN:=1; for i:=1 to N do begin NN:= NN*i ; end; Label1.Caption:= 'Вариантов перестановок: ' + FloatToStr(NN); frmProgress:=TfrmProgress.Create(Self); frmProgress.ProgressBar1.Max:=nn; frmProgress.Show; frmProgress.Update; for j:=1 to NN do begin frmProgress.ProgressBar1.StepIt; frmProgress.Update; Unix2: for m:=1 to N do U[m]:=m; for v:=N downto 1 do begin RR:=Random(v)+1; R[N-v+1]:=U[RR]; for k:=RR to N do begin U[k]:=U[k+1]; end; end; S:=0; for vv:=1 to N do S:= S + R[vv]*Trunc(exp((N-vv)*ln(10))); a[j]:=Trunc(S); for m:=1 to j-1 do begin if a[j]= a[m] then GoTo Unix2 else end; ListBox1.Items.Strings[j-1] :=FloatToStr(a[j])+' ['+ FloatToStr(j)+']'; end; frmProgress.Hide; frmProgress.Free; ListBox1.Items.EndUpdate; end;
Но вот я не могу понять, почему когда я пищу для массива a верхний предел 300000 и более то прога при работе вылетает? Как это исправить т.к. хочется получить генерацию 9-ти значных РАЗНЫХ чисел а 9!=362880?
Member
Статус: Не в сети Регистрация: 14.08.2003 Откуда: Питер
Ray Adams В том то и дело что никак не увеличить. Максимум 256000 а далее прога вылетает. Как это поправить?
И еще вот что... Как увеличить производительность проги? Пробовал ставить ей Реал-Тайм/Hihg приоритеты - но дивидендов от этого вообще никаких. Только система подвисает.
Advanced member
Статус: Не в сети Регистрация: 09.06.2003 Откуда: USSR
Halfback какая ось стоит?
Производительность увеличивается такими вариантами
1 переписываеш код более оптимизировано
2 часть вычислений перекидываеш на ассемблер
3 апгрейд компа.
Цитата:
Максимум 256000 а далее прога вылетает. Как это поправить?
Потому что Stack Overflow! Кто же создает такого размера переменные в теле функции??? А нафига были созданы динамические массивы?
Вот тебе кусок кода с использованием динамического масства. Но учти! Динамические массивы начинаются с индекса 0. А так как ты использовал массивы 1.. и до. То выделять тебе надо будет на 1 больше чем надо, чтобы не менять сам код.
Только я их кода пока вырубил progressbar, ну сам разюберешся думаю
Код:
procedure TForm1.Button1Click(Sender: TObject); Label Unix2; var N,NN: integer; i,j,v,m,k,vv: integer; S: integer; RR: integer; U: array[1..10] of shortint; R: array[1..10] of shortint; a: array of integer;
begin
SetLength(a,300001); ListBox1.Items.BeginUpdate; ListBox1.Items.Clear; N:= StrToInt(Edit1.Text); //if N>=10 then ShowMessage('Íåïðàâèëüíî ââåäåíî ÷èñëî N'); NN:=1; for i:=1 to N do begin NN:= NN*i ; end; Label1.Caption:= 'Âàðèàíòîâ ïåðåñòàíîâîê: ' + FloatToStr(NN); for j:=1 to NN do begin Unix2: for m:=1 to N do U[m]:=m; for v:=N downto 1 do begin RR:=Random(v)+1; R[N-v+1]:=U[RR]; for k:=RR to N do begin U[k]:=U[k+1]; end; end; S:=0; for vv:=1 to N do S:= S + R[vv]*Trunc(exp((N-vv)*ln(10))); a[j]:=Trunc(S); for m:=1 to j-1 do begin if a[j]= a[m] then GoTo Unix2; end; ListBox1.Items.Strings[j-1] :=FloatToStr(a[j])+' ['+ FloatToStr(j)+']'; end; ListBox1.Items.EndUpdate; SetLength(a,0); end;
Member
Статус: Не в сети Регистрация: 14.08.2003 Откуда: Питер
Ray Adams
Спасибо!!! Все вроде работает. При N=9 прога уже как 30минут считает.
Цитата:
1 переписываеш код более оптимизировано
В каком смысле оптимизированно? Единственно, что тут можно оптимизировать, так это следующий кусок кода:
Цитата:
for m:=1 to N do U[m]:=m; for v:=N downto 1 do begin RR:=Random(v)+1; R[N-v+1]:=U[RR]; for k:=RR to N do begin U[k]:=U[k+1]; end; end;
Более того как помнишь при первом коде когда N=8 прога генерила числа 1.5 минуты а теперь 30сек. А оптимизацию остального я не вижу возможным.
Цитата:
часть вычислений перекидываеш на ассемблер
, Я ассемблер вообще не знаю. Может поможешь с этими вставками и дай, если знаешь, ссылочки на это дело.
Цитата:
часть вычислений перекидываеш на ассемблер
Думаю, что этот вариант для меня самый неудобный. Тем более, что виноват в скорости больше сам компилятор в Делфи чем мой проц и FSB.
По поводу производительности вычислений я вот еще что думаю. Я слышал, что можно использовать отдельный поток памяти для прогаммы с помощью Threat. И еще для работы проги вроде можно выделять какую-то часть ОЗУ. Только вот как все это применять я тоже не знаю. Что по этому поводу можешь сказать?
Да, ище. Как мне поставить секундомер выполнения операций? (Т.е. за какое время, например при N=8, прога будет генерить комбинации чисел и выведет их на ProgressBar ).
Member
Статус: Не в сети Регистрация: 15.04.2004 Откуда: Москва
Halfback Есть такая функция. GetTickCount(). Возвращает кол-во мс прошедших с момента старта системы.
Те:
var
StartTime, Duration : Integer;
begin
StartTime := GetTickCount;
.....
Duration := (GetTickCount - StartTime) div 1000; // Время выполнения в секундах
Все здорово, но можешь нарваться на переход через 2 в 32 (т.е. система проработала меньше этого времени до старта и больше по окончании работы ).
Оптимизация.
Все for меняй на while (т.к. у тебя одной из конечных границ есть 1, то все можно свести к банальной проверке на больше/меньше 0).
Все + заменяй на inc(). Не адресуйся к массиву по индексу, а вычисляй указатель. Вот тебе кусок примера:
var
P: PShortInt;
....
m:= 1;
p := @U;
while(N-m > 0) do begin // for m:=1 to N do U[m]:=m;
p^ := m;
inc(m);
inc(p);
end;
Member
Статус: Не в сети Регистрация: 14.08.2003 Откуда: Питер
Avaddon Спасибо за GetTickCount. Все работает. Только вот на строчку
Цитата:
Duration := (GetTickCount - StartTime) div 1000;
выдает предупреждение:
Цитата:
[Warning] Unit1.pas(226): Combining signed and unsigned types - widened both operands
это что-то типа 'комбинируют знаковые и незнаковые типы - оба широкие операнды'?
Не мог бы прокоментировать следующие строки приведенного тобой примера:
Цитата:
P: PShortInt; p := @U; p^ := m;
Добавлено спустя 37 минут, 20 секунд: Ray Adams
Цитата:
какая ось стоит?
WinXP SP1
После 40-ка минут работы прога просто виснет (диспетчер задач пишет, что прога не отвечает), хотя ProgressBar почти уже 100%. Что за крендель? Как можно исправить сию ситуацию?
Advanced member
Статус: Не в сети Регистрация: 09.06.2003 Откуда: USSR
Цитата:
После 40-ка минут работы прога просто виснет (диспетчер задач пишет, что прога не отвечает), хотя ProgressBar почти уже 100%. Что за крендель? Как можно исправить сию ситуацию?
Все нормально, просто при больших числах у тебя внутренний цикл очень большой. И потому с виду зависает.
Цитата:
тем более, что виноват в скорости больше сам компилятор в Делфи чем мой проц и FSB.
Извини за резкость, но не пори чуши плиз . Delphi делает очень хорошо оптимизированный код, также как и луюбой другой язык. Можеш глянуть на него в ассемблерном виде, написано так, как если бы кто-то писал именно на асме .
Цитата:
Я слышал, что можно использовать отдельный поток памяти для прогаммы с помощью Threat
Да , это тоже можно. Создаеш поток, он занимается вычислением, а твоя прога в этот момент может просто отдыхать. В любой момент можеш просто зарезать поток. Но скорости это тебе не прибавит, а наоборот немного замедлит.
Сам видиш, при 9 получается огромное кол-во переборок. Сейчас покопаюсь в коде твоем насчет оптимизаций.
Добавлено спустя 17 минут, 8 секунд: КСтати может опишет, что же ты этим кодом добиваешся то? А то не понятно что ты хочеш добиться и как сортируеш. Может сперва надо создать массив и только после окончания его создания , сортирнуть , скажем бинарным способом?
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения