Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.10.21;
Скачать: CL | DM;

Вниз

Вот как можно ускорить программу?   Найти похожие ветки 

 
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&#133


 
vasIZmax ©   (2007-09-29 17:56) [2]

хз, но не ускоряется все равно, по крайней мере заметна задержка появления формы...


 
Kolan ©   (2007-09-29 21:08) [3]

> хз, но не ускоряется все равно

Показывай как изменил&#133


 
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]

> И вариант о котором ты говорил(сразу не запостил, думал
> что удалил)

Работает? С указателями что-то ты перемудрил&#133


 
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;  //Если по имени файла не понять какой там пользователь, то придется загрузит все ини и искать внутри&#133


Для работы со строками типа 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х связанных таблиц через
> ж&#133 ээ&#133 инишники&#133

Точно, ведь это две таблицыыы. Имхо, если длать именно через инишки, надо написать низкоуровнывее команда типа SELECT * FROM ini WHERE <&#133>
А потом пользуя их построить вызокоуровневые &#133


 
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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.028 c
15-1190608909
DeadLord
2007-09-24 08:41
2007.10.21
из бэйсика в дэлфи


15-1190031263
_aqtime_
2007-09-17 16:14
2007.10.21
Профилировка aqtime


2-1190641305
Terc
2007-09-24 17:41
2007.10.21
дяденки Не посылайте меня HTML


15-1190126267
alex_ant
2007-09-18 18:37
2007.10.21
Автопроверка тестов модулей для D7


15-1190213316
sdubaruhnul
2007-09-19 18:48
2007.10.21
А какой там сайт был...