Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Динамические массивы и указатели


Автор: serakerch 10.9.2015, 11:16
Доброе время суток знатоки.
Помогите ускорить немного код , его суть создания дерева из входящих данных ( данные о сетевом пакете: протокол, исх ip, порт, вход ip, порт, размер данных )

переменные и типы
Код

 Tdp=record
    dp:integer;
    size:integer;
  end;
  Tdip=record
    dip:integer;
    dp:array of Tdp;
  end;
  Tsp=record
    sp:integer;
    dip:array of Tdip;
  end;
  Tsip=record
    sip:integer;
    sp:array of Tsp;
  end;
  Tp=record
    p:integer;
    sip:array of Tsip;
  end;

var
paket:array of Tp;

процедура записи данных
Код

procedure ip1CapI(proto, sourceIP, destIP,
  SourcePort, DestPort: Integer; data_size: Integer);
var i,k:integer;
  p,sip,sp,dip:integer;
  f:boolean;
begin
// proto
 f:=false;
 k:=high(paket);
 for i:=0 to k do
  if proto=paket[i].p then begin
   p:=i;
   f:=true;
   break;
  end;
 if not f then begin
   k:=k+1;
   SetLength(paket,k+1);
   paket[k].p:=proto;
   p:=k;
 end;
// sourceIP
 f:=false;
 k:=high(paket[p].sip);
 for i:=0 to k do
  if sourceIP=paket[p].sip[i].sip then begin
   sip:=i;
   f:=true;
   break;
  end;
 if not f then begin
   k:=k+1;
   SetLength(paket[p].sip,k+1);
   paket[p].sip[k].sip:=sourceIP;
   sip:=k;
 end;
// SourcePort
 f:=false;
 k:=high(paket[p].sip[sip].sp);
 for i:=0 to k do
  if SourcePort=paket[p].sip[sip].sp[i].sp then begin
   sp:=i;
   f:=true;
   break;
  end;
 if not f then begin
   k:=k+1;
   SetLength(paket[p].sip[sip].sp,k+1);
   paket[p].sip[sip].sp[k].sp:=SourcePort;
   sp:=k;
 end;
// destIP
 f:=false;
 k:=high(paket[p].sip[sip].sp[sp].dip);
 for i:=0 to k do
  if destIP=paket[p].sip[sip].sp[sp].dip[i].dip then begin
   dip:=i;
   f:=true;
   break;
  end;
 if not f then begin
   k:=k+1;
   SetLength(paket[p].sip[sip].sp[sp].dip,k+1);
   paket[p].sip[sip].sp[sp].dip[k].dip:=destIP;
   dip:=k;
 end;
// DestPort
 f:=false;
 k:=high(paket[p].sip[sip].sp[sp].dip[dip].dp);
 for i:=0 to k do
  if DestPort=paket[p].sip[sip].sp[sp].dip[dip].dp[i].dp then begin
   paket[p].sip[sip].sp[sp].dip[dip].dp[i].size:=paket[p].sip[sip].sp[sp].dip[dip].dp[i].size+data_size;
   f:=true;
   break;
  end;
 if not f then begin
   k:=k+1;
   SetLength(paket[p].sip[sip].sp[sp].dip[dip].dp,k+1);
   paket[p].sip[sip].sp[sp].dip[dip].dp[k].dp :=DestPort;
   paket[p].sip[sip].sp[sp].dip[dip].dp[k].size :=data_size;
   inc(savep);
 end;

запись данных в базу
Код

procedure save2base;
var
 i,p,kp:integer;
 sip,ksip,sp,ksp,dip,kdip,dp,kdp:integer;
 ps,sips,sps,dips,dps,ss,dt:string;
begin
   dt:=IntToStr(DateTimeToUnix(date+time));
   if not sldb.isTransactionOpen then
    sldb.BeginTransaction;
   kp:=high(paket);
   for p:=0 to kp do begin
    ps:=CheckProtocol(paket[p].p);
    ksip:=high(paket[p].sip);
    for sip:=0 to ksip do begin
     sips:=inttostr(paket[p].sip[sip].sip);
     ksp:=high(paket[p].sip[sip].sp);
     for sp:=0 to ksp do begin
      sps:=inttostr(paket[p].sip[sip].sp[sp].sp);
      kdip:=high(paket[p].sip[sip].sp[sp].dip);
      for dip:=0 to kdip do begin
       dips:=inttostr(paket[p].sip[sip].sp[sp].dip[dip].dip);
       kdp:=high(paket[p].sip[sip].sp[sp].dip[dip].dp);
       for dp:=0 to kdp do begin
        dps:=inttostr(paket[p].sip[sip].sp[sp].dip[dip].dp[dp].dp);
        ss:=inttostr(paket[p].sip[sip].sp[sp].dip[dip].dp[dp].size);
        sldb.ExecSQL('insert into net (time,prot,ip1,port1,ip2,port2,size) values("'
            +dt+'","'+ps+'","'+sips+'","'+sps+'","'+dips+'","'+dps+'","'+ss+'")');
       end;
       SetLength(paket[p].sip[sip].sp[sp].dip[dip].dp,0);
      end;
     SetLength(paket[p].sip[sip].sp[sp].dip,0);
     end;
     SetLength(paket[p].sip[sip].sp,0);
    end;
    SetLength(paket[p].sip,0);
   end;
   SetLength(paket,0);
  sldb.Commit;

В общем сама суть в том что "paket[p].sip[sip].sp[sp].dip[dip].dp[dp].size" вот такое обращение долго работает, как его можно сократить?
пробовал :
Код

tpdp:array of Tdp
pointer(ptdp):=paket[p].sip[sip].sp[sp].dip[dip].dp;
// или
ptdp:=@paket[p].sip[sip].sp[sp].dip[dip].dp;
 
не работает (((

буду признателен за подсказку, заранее спасибо!

Автор: Illusion Dolphin 11.9.2015, 10:14
Цитата

В общем сама суть в том что "paket[p].sip[sip].sp[sp].dip[dip].dp[dp].size" вот такое обращение долго работает, как его можно сократить?

А вы проверяли строчку
Код

sldb.ExecSQL('insert into net (time,prot,ip1,port1,ip2,port2,size) values("'
            +dt+'","'+ps+'","'+sips+'","'+sps+'","'+dips+'","'+dps+'","'+ss+'")');

? Мне кажется, что эта строка должна быть куда медленнее smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)