Форум: "Начинающим";
Текущий архив: 2009.03.15;
Скачать: [xml.tar.bz2];
ВнизОптимизация скорости вывода на екран с помощью Label Найти похожие ветки
← →
GVas © (2009-01-04 14:53) [0]Добрый день.
На форме вывожу информацию вот так
procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
begin
For i:=1 to 100000 do
Begin
Label1.Caption:=IntToStr(i);
Label1.Refresh;
End;
end;
оптимальна ли с точки быстродействия такая конструкция, потому как на довольно мощном компе такая по сути простая операция занимает довольно много времени (8 секунд где-то (или 200000 тактов процессора на одно обновление значения)) и заметил что в некоторых случаях загружаются разные ядра процессора (но одновременно только одно). Спасибо за ответы.
← →
sniknik © (2009-01-04 15:08) [1]> оптимальна ли с точки быстродействия такая конструкция
а подумать? ты там все цифры разглядеть успеваешь?
> 8 секунд
а вот такая
procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
begin
For i:=1 to 100000 do
Begin
//Label1.Caption:=IntToStr(i);
//Label1.Refresh;
End;
Label1.Caption:=IntToStr(100000);
end;
0 сек. при том же конечном результате.
← →
GVas © (2009-01-04 16:03) [2]ну мб я просто неправильно выразил мысль но существует ли в делфи способ вывода на экран отличный от Label, но работающий быстрее брал я 100000 просто для того чтобы приблизительно высчитать скорость вывода на экран и даже если взять Label1.Caption:=IntToStr(100000) то это получатся почти те же самые 200к тактов процесора (чуть меньше) а если программа каждую секунду обновляет пару сотен таких Label и перед этим обсчитывает какие-то головоломные масивы информации хотелось бы немного оптимизировать работу. Подскажите, или я занимаюсь ерундой и на нынешних скоростях процессора это будет не очень заметно?
← →
sniknik © (2009-01-04 16:34) [3]> или я занимаюсь ерундой
занимаешься ерундой, но вовсе не из за скоростей процессора, а из-за того что пытаешься оптимизировать то, что в этом не нуждается... ->
лебел, как и другие компоненты предназначенные для отображения, они для юзера, т.е. чтобы юзер видел инфу, а юзер физически не может реагировать так быстро... т.е. достаточно выводить только то что он способен заметить и осознать, и если инфа будет меняться раз в пол секунды этого будет достаточно... и для этого на всю твою проверку достаточен всего 1 вызов (и он останется одним даже если цикл еще на пару порядков увеличить)... и какая нужна оптимизация одного вызова? а она реально нужна в данном случае всего одна при правильной логике.
понятно что у тебя там будут еще вычисления, но... какую долю времени займут обновления интерфейса. если отображать только достаточное для юзера?
вот например чтобы вызвать 100000 раз (в нормальном варианте) у тебя вычисления должны идти 14 часов... и что в этой доле будут занимать 8 сек?
← →
AndreyV © (2009-01-04 16:47) [4]> [3] sniknik © (04.01.09 16:34)
Кстати, и 0.5 секунд для лейбл, а тем более для "пары сотен", - слишком часто, тут надо стрелки рисовать.
← →
GVas © (2009-01-04 17:26) [5]Спасибо за ответ, все понятно, но если можно еще один вопрос есть IntToStr а такая же функция для вещественных чисел присутствует?? и еще момент при работе цикла нельзя нажать на какую либо другую кнопку, как выйти из такого положения?
← →
{RASkov} © (2009-01-04 17:30) [6]> а такая же функция для вещественных чисел присутствует??
Да, FloatToStr()
> нельзя нажать на какую либо другую кнопку, как выйти из
> такого положения?
Application.Processmessage;
или доппотоки....
← →
GVas © (2009-01-04 17:47) [7]Вот решил проверить как работает математика в делфе взял вещественное число 1Е-17 прибавил его 100000 раз получается 9,99999988197267E-13 а должно быть 1е-12 почему такая разница получается????
← →
GVas © (2009-01-04 17:53) [8]Мдя, все извините за беспокойство оказалось что real48 мало знаков в числе поддерживает, значит ли это что если прибавлять к очень большому числу очень маленькое, будет погрешность??
← →
AndreyV © (2009-01-04 18:00) [9]> [8] GVas © (04.01.09 17:53)
Раз в неделю появляется этот вопрос
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=374
← →
GVas © (2009-01-04 19:39) [10]Ну из статьи я ситуацию понял, но пути ее решения кроме того что лучше вместо реала использовать екстендед, ну это по правде говоря я и експерементально получил, а вот что делать если мне нужно больше чем 20 знаков после запятой??
← →
Сергей М. © (2009-01-04 19:56) [11]
> что делать если мне нужно больше чем 20 знаков после запятой?
Ты что, Левша лесковский ?
← →
sniknik © (2009-01-04 19:58) [12]> а вот что делать если мне нужно больше чем 20 знаков после запятой??
путь до альфы центавра с точностью приземления до миллиметра вычитываешь?
дерзай. но это уже не стандарт, и считай стандартных типов таких нет. но есть библиотеки для работы с большими числами. ищи.
← →
Anatoly Podgoretsky © (2009-01-04 21:01) [13]> GVas (04.01.2009 19:39:10) [10]
Ситуация простая, никогда не использовать Real48 и читать что по этому поводу говорит справка,
← →
Anatoly Podgoretsky © (2009-01-04 21:03) [14]> GVas (04.01.2009 19:39:10) [10]
Что то не то, то хватало Real48, а теперь не хватает Extended?
И объясни почему тебе нужна такая большая точность или ты просто так, что вижу, то и пою.
← →
GVas © (2009-01-04 21:29) [15]Всю глубину своего заблуждения я понял, будем пользоваться тем что есть, а как лучше (или легче) организовать параллельные процессы в программе с помощью потоков или с помощью Application.Processmessage?? для начинающего. Учитывая что параллельно должен выполняться определенный набор команд ну скажем раз в секунду.
← →
GVas © (2009-01-04 21:45) [16]to Anatoly Podgoretsky
первый раз я использовал реал48 для того чтоб создать переменную вещественного типа потом узнал каким способом ее можно преобразовать, после того как начал считать число мелкое получилось не то какое я хотел, начал разбираться почему не то, сменил тип на екстендед, когда нет превышения все нормально, а когда есть то снова погрешность получается вот так.
← →
sniknik © (2009-01-04 22:00) [17]> Application.Processmessage
это к параллельности процессов имеет слабое отношение... (если вообще хоть какое то)
> Учитывая что параллельно должен выполняться определенный набор команд ну скажем раз в секунду.
таймером не обойдешься?
если этот набор команд выполняется всего раз, в целую секунду, то значит комп у тебя в основном простаивает, и нет нужды париться с каким то там параллелизмом...
← →
GVas © (2009-01-04 22:26) [18]Ех, не умею я еще объяснять толком, значит такая ситуация: моделируется физический процесс, данные которые будут получены должны каждую секунду (или пару секунд) выдаваться на екран, ну а процесс он в принципе должен протекать в реальном времени и постоянно пока не прервеш его выполнение.
← →
sniknik © (2009-01-04 22:53) [19]таймер. однозначно.
← →
Anatoly Podgoretsky © (2009-01-04 23:45) [20]> GVas (04.01.2009 22:26:18) [18]
Да тут сначала надо думать об смене индикации, обновление 200 меток раз в секунду, да пользователь свихнется. Цифровое представление не подходит, никто не в силах даже заметить в каких метках изменилась информация. Переходи на гистограммы.
← →
GVas © (2009-01-05 00:05) [21]Ясно, спасибо за помощь, всем кто участвовал, дельные и понятные ответы, ну сначала хотя бы написать в общем алгоритм работы, а как выводить метками или гистограммами это уже после того как напишу буду решать, для себя хотя бы метками чтобы было понятно что и как конкретно изменятся ,а вобще я думал просто подсвечивать фон тех параметров которые выходят за границу дозволенных режимов, и чтоб на ходу можно было подстраивать работу модели меняя в ту или иную сторону.
← →
GVas © (2009-01-05 00:07) [22]Если возможно не закрывайте тему чтоб я мог еще дописывать вопросы, или для новых нужно открывать отдельную?
← →
Германн © (2009-01-05 00:22) [23]
> или для новых нужно открывать отдельную?
Если "новые" вопросы будут на темы не связанные никак с сабжем, то новую.
← →
GVas © (2009-01-13 22:51) [24]Уважаемые еще вопрос по оптимизированности программы что лучше использовать? Есть довольно большое количество данных, которые в принципе константы, но их можно вычислить с помощью формулы, в программу лучше вбивать эту кучу констант (в массив например, с последующим использованием) или использовать формулу, ну и второй вопрос если есть данные в файле например текстовом, с помощью какой команды их можно присвоить какой то стринговой переменной и вобще какой формат файла использовать лучше? просто текст или дбф или еще какой??
← →
anonims (2009-01-14 10:55) [25]const pi=3.14;
x2pi=2*pi;
halfpi=pi/2;
var:=pi/2;
var:=halfpi;
в любом случае вычисление правой части берет на себя транслятор, т.е. в программном коде будет использовано уже вычисленное значение.
использвать вариант при котором читаемость программы будет выше
TiniFile Кead... Write...
← →
GVas © (2009-01-14 22:41) [26]Так, я поздравляю всех с праздником, желаю в новом году всем чтоб программы создавались на раз два, и без ошибок самое главное, спасибо всем кто помагал в создании программы, извините за сумбурность, праздник как никак
← →
han_malign © (2009-01-15 13:21) [27]
> моделируется физический процесс, данные которые будут получены
> должны каждую секунду (или пару секунд) выдаваться на екран
State: Структура данных описывающих Состояние модели.
Slide: Метод получения следующего Состояния
Show: Метод визуализации Состояниия
1.TForm1.OnTimer(Sender: TObject);
- предпочтителен если Slide - явная функция от времени(то бишь "шаг" между состояними произвольный, например: прямолинейное равноускренное движение) и/или вычисление занимет мало времени...
var state: TState;
begin
state:= Slide(FState, Now);
FState:= state.
Show(FState);
end;
ВНИМАНИЕ: Если в Slide вызывать ProcessMessages - может возникнуть рекурсия, если метод не уложится в интервал таймера
OnTimer{ Slide{ ProcessMessages{ GetMessage:WM_TIMER{ далее понятно } } } }
лечится флагом
if( FOnSlide = 0 )then begin
inc(FOnSlide);
...
dec(FOnSlide);
end;
2.TThread1.Create(synchronous: boolean);
begin
FSync:= CreateEvent(nil, not synchronous, true, nil);
InitializeCriticalSection(FCrit);
inherited Create(false);
end;
TThread1.Destroy;
begin
Terminate;
WakeUp;
inherited;
end;
TThread1.Sleep;
begin
ResetEvent(FSync);
end;
TThread1.WakeUp;
begin
SetEvent(FSync);
end;
TThread1.Execute;
var nextFrame: integer;
begin
while not Terminated of begin
WaitForSingleObject(FSync, INFINITE);
nextFrame:= FFrame + 1;
if(nextFrame > High(FState))then nextFrame:= Low(FState);
FState[nextFrame]:= Slide({in}FState[FFrame]);
EnterCriticalSection(FCrit);
FFrame:= nextFrame;
LeaveCriticalSection(FCrit);
Sleep(0);//take a chance for other threads
end;
end;
TTread1.Snapshot: TState;
begin
EnterCriticalSection(FCrit);
Result:= FState[FFrame];
LeaveCriticalSection(FCrit);
WakeUp;
end;
..............
TForm1.OnTimer(Sender: TObject);
begin
Show(FThread1.Snapshot);
end;
2.1.TForm1.Show(state: TState);
begin
if(FState.Ticker <> state.Ticker)then begin
FState:= state;
Invalidate;
end;
end;
TForm1.OnPaint(Sender: TObject);
begin
Draw(FState);
end;
← →
tesseract © (2009-01-15 13:28) [28]
> Sleep(0);//take a chance for other threads
индусятина, при waitforsingleobject не нужен. Использовать желательно WaitForMultipleObject где одно из событий - приказ потоку сгинуть.
← →
han_malign © (2009-01-15 13:47) [29]
> индусятина, при waitforsingleobject не нужен.
FSync:= CreateEvent(nil, not synchronous, true, nil);
если FSync - всегда взведен получим 100% загрузку CPU, что - в случае одного ядра - приведет как минимум к тормозам...
WaitForMultipleObject - согласен, но это ж сколько лишних строк писать(если уж меня заломало ветвление по флагу (FSynchronous:= synchronous) прописывать)...
З.Ы. в TThread1.Destroy - не забыть прибить FSync и FCrit(дабы не изменять религии)...
← →
tesseract © (2009-01-15 13:59) [30]
> WaitForMultipleObject - согласен, но это ж сколько лишних
> строк писать(если уж меня заломало ветвление по флагу
Около 15 вроде. Считая интеграцию в класс потока.
← →
GVas © (2009-01-15 21:08) [31]спасибо за ответ, правда мне еще очень далеко до того уровня когда пойму что здесь написано, но будем разбираться, я же сделал вот так (в смысле подсмотрел как делать)
пока что по кнопке, но в будущем по таймеру
procedure TForm1.Button1Click(Sender: TObject);
begin
ModelThread.Create(False);
end;
это в подключаемом модуле
procedure ReactorThread.ShowResult;
begin
Form1.Edit1.Text := IntToStr(answer);
end;
цикл для примера взят, потом вместо него модель будет
procedure ModelThread.Execute;
var
i: Integer;
begin
for i := 1 to 10000 do
begin
answer := answer + 1;
Synchronize(ShowResult);
end;
end;
← →
GVas © (2009-01-23 19:58) [32]Подскажите пожалуйста как и с помощью чего лучше вывести на экран колонку строк размером хотя бы пару десятков строк. Спасибо за ответы.
← →
GVas © (2009-01-23 21:12) [33]И в догонку пытаюсь присвоить переменной имя файла с помощью АssignFile(F,"C:\Program Files\Borland\Delphi7\Projects\1.txt")
Значение переменной не изменяется почему то, как быть???
← →
GVas © (2009-01-23 21:19) [34]с присваиванием имени файла разобрался, почему то в Watch list не отображалось значение переменной
← →
sniknik © (2009-01-23 21:27) [35]> я же сделал вот так
т.е. все объяснения впустую... ;(, скорблю по так и не состоявшемуся программисту, и да здравствует будущий дворник! ;)
> вывести на экран колонку строк размером хотя бы пару десятков строк.
дбгрид
> Значение переменной не изменяется почему то, как быть???
бери упорством, меняй пока она не согласится с новым значением... :)
← →
AndreyV © (2009-01-23 21:28) [36]> [32] GVas © (23.01.09 19:58)
> Подскажите пожалуйста как и с помощью чего лучше вывести
> на экран колонку строк размером хотя бы пару десятков строк.
> Спасибо за ответы.
А TLable уже не устраивает?
Если количество меняется, можно попробовать TStringGrid, как наиболее универсальный.
← →
tesseract © (2009-01-23 21:34) [37]
> почему то в Watch list не отображалось значение переменной
Давно так не ржал. Какую переменную ты хочешь посмотреть? Файл со своим именем связан, как Фомич с бутылкой водки - ему что на этикетке до фонаря.
← →
GVas © (2009-01-23 21:46) [38]
> т.е. все объяснения впустую... ;(, скорблю по так и не состоявшемуся
> программисту, и да здравствует будущий дворник! ;)
Ну ИМХО в том что я написал (скопировал, а потом переделал) я хотя бы приблизительно разобрался, а вот то что было написано уважаемым han_malign я больше половины не понимаю, как можно использовать код не понимая, что он делает
AndreyV спасибо за ответ, будем пытаться,
tesseract вот как хорошо получилось, продлил жизнь еще одному человеку))
← →
sniknik © (2009-01-23 22:03) [39]> Ну ИМХО в том что я написал (скопировал, а потом переделал) я хотя бы приблизительно разобрался, а вот то что было написано уважаемым han_malign я
> больше половины не понимаю, как можно использовать код не понимая, что он делает
а то, что сам написал говоришь понимаешь? а то что я в первом, третьем посте написал, это по китайски? с чего у тебя в 31м посте та же ахинея что и в 0-м?
← →
GVas © (2009-01-23 22:23) [40]sniknik
> с чего у тебя в 31м посте та же ахинея что и в 0-м?
У меня там такие строки просто для проверки работоспособности потока, я во время работы цикла жал на вторую кнопку на форме и программа заканчивала свою работу, вот поэтому у меня там и цикл, просто чтоб проверить как поток работает, и смогу ли я выйти из программы во время работы цикла, а написал я насчет "я хотя бы приблизительно разобрался, а вот то что было написано уважаемым han_malign" имея ввиду пост № 27, я просто неправильно выразился((
Ну и в догонку, каким образом можно в поток ввести какие либо данные из основной программы???
И еще как сделать свой тип данных, например, чтоб он назывался myarrey и состоял из двух массивов заданного размера i1:array[1..10] of Integer; i2:array[1..10] of Real. обращение я так понимаю к отдельному елементу будет что то типа т1.и1 или т1.и2.
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.03.15;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.046 c