Форум: "Начинающим";
Текущий архив: 2007.10.21;
Скачать: [xml.tar.bz2];
ВнизВот как можно ускорить программу? Найти похожие ветки
← →
vasIZmax © (2007-09-28 23:53) [0]Смысл ТЗ такой:
Есть два ини файла. В первом данные хранятся так[Name]
id1=имя
id2=имя
...
id1000=имя
[Score]
id1=число
id2=число
...
id1000=число
А второй ини с данными о пользователе:[User]
User=имя
[Score]
Score=число
Нужно вывести в СтрингГрид отсортированый ини1 по секции score, с учетом данных из ини2.
(грубо говоря, определить какое место среди всех записанных в ини2 будет занимать user из ини2, типо таблицы рейтинга).
Сделал все, но работает медленно. Хотелось бы ускорить. Ниже код с комментами.
//считаю сколько этих самых id в ини1
d:=tstringlist.Create;
ini := TIniFile.Create(extractfilepath(paramstr(0))+"\score\sco.ini");
try
begin
ini.ReadSection("name",d);
end;
finally
ini.Free;
end;
//устанавливаю длины массивов, в ааа - для записывания чисел, а bbb - для имен
setlength(aaa,d.Count+1);
setlength(bbb,d.Count+1);
//в переменные считываю данные о пользователе
ini := TIniFile.Create(extractfilepath(paramstr(0))+"\user\"+form5.login+".ini");
ballProm:=ini.ReadInteger("Ball","Ball",0);
LoginProm:=ini.ReadString("Login","Login","");
ini.Free;
//заполняю массивы
ini := TIniFile.Create(extractfilepath(paramstr(0))+"\score\sco.ini");
d1:=TstringList.Create;
for i:=low(aaa) to high(aaa) do
if i=0 then
begin
aaa[i]:=ballProm;
bbb[i]:=LoginProm;
d1.Add(inttostr(ballProm));
end
else
begin
aaa[i]:=ini.ReadInteger("Score","id"+inttostr(i),0);
bbb[i]:=ini.ReadString("Name","id"+inttostr(i),"");
d1.Add(ini.ReadString("Score","id"+inttostr(i),"0"));
end;
ini.Free;
//сортирую
sort(aaa);
//вывожу в стринггрид.
for i:=low(aaa) to high(aaa) do
begin
//вывел число из отсортированного массиваform7.stringgrid1.Cells[0,i+1]:=inttostr(aaa[i]);
// сопоставляю числу его имя
for j:=low(aaa) to high(aaa) do
if (aaa[i]=strtoint(d1.Strings[j])) then
form7.stringgrid1.Cells[1,i+1]:=bbb[j];
end;
form7.StringGrid1.RowCount:=high(aaa)+1;
form7.ShowModal;
//чищу памятьaaa:=nil;
bbb:=nil;
d.Free;
d1.Free;
Сортирую так:procedure Sort(var A: array of Integer);
var
I, J, T: Integer;
begin
for I := Low(A)+1 to High(A) do
for J := High(A) downto I + 1 do
if A[I] > A[J] then
begin
T := A[I];
A[I] := A[J];
A[J] := T;
end;
end;
Все работает, но надо б ускорить. Вопрос как? Или по другому не получится?
ЗЫ. Имхо, медлительность работы из-за вывода в стринггрид, покА он это все отобразит, поэтому так медленно.
← →
Kolan © (2007-09-29 09:39) [1]Считывай из Ini в лист и сортируй его средствами. Получишь QuickSort…
← →
vasIZmax © (2007-09-29 17:56) [2]хз, но не ускоряется все равно, по крайней мере заметна задержка появления формы...
← →
Kolan © (2007-09-29 21:08) [3]> хз, но не ускоряется все равно
Показывай как изменил…
← →
vasIZmax © (2007-09-29 21:12) [4]остановился на этом варианте
type ddd = array of array of integer;
procedure TForm1.QuickSort(a: ddd; min, max: integer);
Var
i,j,mid, tmp, tmpName: integer;
Begin
if min<max then
begin
mid:=A[0,min];
i:=min-1;
j:=max+1;
while i<j do begin
repeat
i:=i+1;
until A[0,i]>=mid;
repeat
j:=j-1;
until A[0,j]<=mid;
if i<j then begin
tmp:=A[0,i];
A[0,i]:=A[0,j];
A[0,j]:=tmp;
tmpName:=A[1,i];
A[1,i]:=A[1,j];
A[1,j]:=tmpName;
end;
end;
QuickSort(a, min,j);
QuickSort(a, j+1,max);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
ini: TIniFile;
d,dName:Tstringlist;
LoginProm:string;
ballProm,i,j, T,t1: Integer;
aaa: ddd;
begin
d:=tstringlist.Create;
ini := TIniFile.Create("\sco.ini");
try
begin
ini.ReadSection("name",d);
end;
finally
ini.Free;
end;
setlength(aaa,2,d.Count+1);
ini := TIniFile.Create("\user.ini");
ballProm:=ini.ReadInteger("Ball","Ball",0);
LoginProm:=ini.ReadString("Login","Login","");
ini.Free;
dName:=Tstringlist.Create;
ini := TIniFile.Create("\sco.ini");
for i:=0 to d.Count do
if i=0 then
begin
aaa[0,i]:=ballProm;
aaa[1,i]:=i;
dname.Add(LoginProm);
end
else
begin
aaa[0,i]:=ini.ReadInteger("Score","id"+inttostr(i),0);
aaa[1,i]:=i;
dname.Add(ini.ReadString("Name","id"+inttostr(i),"0"));
end;
ini.Free;
form1.QuickSort(aaa,0,d.Count);
for I := 0 to high(aaa[0]) do
begin
form1.StringGrid1.Cells[0,i+1]:=inttostr(aaa[0,i]);
form1.StringGrid1.Cells[1,i+1]:=dname.Strings[aaa[1,i]];
end;
form1.StringGrid1.RowCount:=d.Count+1;
end;
← →
vasIZmax © (2007-09-29 21:17) [5]И вариант о котором ты говорил(сразу не запостил, думал что удалил)
type Pdouble=^Integer;
function Comp(Item1, Item2:Pointer):integer;
begin
if PDouble(Item1)^<Pdouble(item2)^ then
result:=-1
else
if PDouble(Item1)^>Pdouble(item2)^ then
result:=1
else
result:=0;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
nows, last:Tdatetime;
k:integer;
List,listName:Tlist;
pd,ps:pdouble;
ini: TIniFile;
d,dName:Tstringlist;
LoginProm:string;
ballProm,i,j:integer;
begin
timer1.Enabled:=true;
d:=tstringlist.Create;
ini := TIniFile.Create("\sco.ini");
try
begin
ini.ReadSection("name",d);
end;
finally
ini.Free;
end;
ini := TIniFile.Create("\user.ini");
ballProm:=ini.ReadInteger("Ball","Ball",0);
LoginProm:=ini.ReadString("Login","Login","");
ini.Free;
dName:=tstringlist.Create;
ini := TIniFile.Create("\user.ini");
list:=tlist.Create;
listname:=tlist.Create;
for i:=0 to d.Count do
if i=0 then
begin
New(pd);
New(ps);
Pd^:=ballProm;
ps^:=ballProm;
list.Add(pd);
listname.Add(ps);
dName.Add(LoginProm);
end
else
begin
New(pd);
New(ps);
Pd^:=ini.ReadInteger("Score","id"+inttostr(i),0);
Ps^:=ini.ReadInteger("Score","id"+inttostr(i),0);
dName.Add(ini.ReadString("Name","id"+inttostr(i),""));
list.Add(pd);
listname.Add(ps);
end;
d.Free;
list.Sort(comp);
for k:=0 to list.Count-1 do
begin
pd:=list[k];
for j:=0 to listname.Count-1 do
begin
ps:=listname[j];
if pd^=ps^ then
begin
form1.StringGrid1.Cells[0,k+1]:=floattostr(pd^);
form1.StringGrid1.Cells[1,k+1]:=dname.Strings[j];
dispose(ps);
end;
end;
dispose(pd);
end;
form1.StringGrid1.RowCount:=list.Count+1;
ini.Free;
list.Free;
listname.Free;
end;
← →
Kolan © (2007-09-29 21:46) [6]1. Я это прочесть не могу, сравни свой код с VCL и отформатируй по образцу.
2. Прорефакторь, что тут можно понять вообще, каша :(
← →
Kolan © (2007-09-29 21:50) [7]> И вариант о котором ты говорил(сразу не запостил, думал
> что удалил)
Работает? С указателями что-то ты перемудрил…
← →
vasIZmax © (2007-09-29 21:58) [8]так лучше? (с форматированием постоянно проблема:()
type ddd = array of array of integer;
procedure TForm1.QuickSort(a: ddd; min, max: integer);
Var
i,j,mid, tmp, tmpName: integer;
Begin
if min<max then
begin
mid:=A[0,min];
i:=min-1;
j:=max+1;
while i<j do
begin
repeat
i:=i+1;
until A[0,i]>=mid;
repeat
j:=j-1;
until A[0,j]<=mid;
if i<j then
begin
tmp:=A[0,i];
A[0,i]:=A[0,j];
A[0,j]:=tmp;
tmpName:=A[1,i];
A[1,i]:=A[1,j];
A[1,j]:=tmpName;
end;
end;
QuickSort(a, min,j);
QuickSort(a, j+1,max);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
ini: TIniFile;
d,dName:Tstringlist;
LoginProm:string;
ballProm,i,j, T,t1: Integer;
aaa: ddd;
begin
d:=tstringlist.Create;
ini := TIniFile.Create("\sco.ini");
try
ini.ReadSection("name",d);
finally
ini.Free;
end;
setlength(aaa,2,d.Count+1);
ini := TIniFile.Create("\user.ini");
ballProm:=ini.ReadInteger("Ball","Ball",0);
LoginProm:=ini.ReadString("Login","Login","");
ini.Free;
dName:=Tstringlist.Create;
ini := TIniFile.Create("\sco.ini");
for i:=0 to d.Count do
if i=0 then
begin
aaa[0,i]:=ballProm;
aaa[1,i]:=i;
dname.Add(LoginProm);
end
else
begin
aaa[0,i]:=ini.ReadInteger("Score","id"+inttostr(i),0);
aaa[1,i]:=i;
dname.Add(ini.ReadString("Name","id"+inttostr(i),"0"));
end;
ini.Free;
form1.QuickSort(aaa,0,d.Count);
for I := 0 to high(aaa[0]) do
begin
form1.StringGrid1.Cells[0,i+1]:=inttostr(aaa[0,i]);
form1.StringGrid1.Cells[1,i+1]:=dname.Strings[aaa[1,i]];
end;
form1.StringGrid1.RowCount:=d.Count+1;
end;
> Kolan © (29.09.07 21:50) [7]
Работает.
← →
Kolan © (2007-09-30 09:21) [9]Нет, так тоже плохо.
> так лучше? (с форматированием постоянно проблема:()
http://www.citforum.ru/programming/delphi/style_delphi
Далее
1. Зачем самому делать QuickSort если он уже сделан: см. TList.Sort.
Более того он есть в TStringList.
2. Итого алгоритм примерно такой:
1. Загружаем секцию Name и секцию Souce в TStringList.
2. Теперь нужно подставить числа. Проходимся по списку с именами.
Для каждого имени загружаем ini пользователя вытаскиваем оттуда число и записываем в StringList с Source.
Какие надо сделать методы:function LoadNames(IniFile: TIniFile): TStrings; //Можно передавать имя файла и создавать TIniFile внутри, но будет чуть дольше
function LoadScore(IniFile: TIniFile): TStrings;
function LoadUserValue(FileName, UserName: string): string; //Если по имени файла не понять какой там пользователь, то придется загрузит все ини и искать внутри…
Для работы со строками типа A=B у StringList есть Names и Values.
Как только загрузил все что надо используй метод Sort.
← →
sniknik © (2007-09-30 10:22) [10]вот такая вот эпопея эмуляции 2х связанных таблиц через ж.. ээ.. инишники...
не лучше ли делать на том, что предназначено для обработки данных? таблицах/датасетах (если ini это из тз. то "вкачать" их в виртуальные детасеты и как угодно уже там объеденять/сортировать)
← →
Slym © (2007-10-01 08:00) [11]ТМеmInifile не быстрее?
← →
Kolan © (2007-10-01 08:30) [12]> вот такая вот эпопея эмуляции 2х связанных таблиц через
> ж… ээ… инишники…
Точно, ведь это две таблицыыы. Имхо, если длать именно через инишки, надо написать низкоуровнывее команда типаSELECT * FROM ini WHERE <…>
А потом пользуя их построить вызокоуровневые …
← →
vasIZmax © (2007-10-01 13:12) [13]> Kolan © (30.09.07 09:21) [9]
А если юзать sort при каждом добавлении score?
Я вот как алгоритм строил:
1. Считали данные с файла юзера и записал в StringList(это, я потом на двумерные динамиты перешел, но смысл не изменился) в string[0].
2. Потом считываю все необходимые данные из файла с общими данными.
3. Сортирую
4. Вывожу пользователю.
> sniknik © (30.09.07 10:22) [10]
ТЗ не сводится к конкретному использованию ini, а скорее к такому "делай как хочешь, главное быстро и надежно".
Для 1000 записей использовать датасеты... надо бут попробовать, посмотреть.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.10.21;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.044 c