@
esistem
Size bir örnek hazırladım, aşağıdaki şekilde bir deneyin bakalım farkı görebilecek misiniz ?
* Burada MatchStr kesinlikle
kullanılmıyor, onun yerine indexli (sıralı) array olmak kaydıyla, MatchStr fonksiyonu benzeri bir karşılaştırma yapıyor.
* Tek farkı size yukarıda belirttiğim şekilde sıçrama ile eleme yaparak performans arttırma işlemi var..
function SearchArray( aSrc : String; const aArray: Array of String ): boolean;
const
MakulElemanSayisi = 10;
var
i, LSayac, idxBas, idxSon, iOrta : Integer;
begin
Result := False;
idxBas := Low (aArray);
idxSon := High(aArray);
LSayac := High(aArray)+1;
iOrta := (idxSon - idxBas) div 2;
repeat
if aSrc > aArray[iOrta] then begin
idxBas := iOrta+1;
//idxSon := Aynı...
iOrta := iOrta + (idxSon - idxBas) div 2;
LSayac := (idxSon - idxBas + 1);
end else
if aSrc < aArray[iOrta] then begin
//idxBas := Aynı...
idxSon := iOrta -1;
iOrta := idxBas + (idxSon - idxBas) div 2;
LSayac := (idxSon - idxBas + 1);
end
else Result := True; // tesadüfen bulundu... :)
until ( LSayac <= MakulElemanSayisi ) or Result;
i := idxBas;
while (not result) AND (i <= idxSon) do begin
Result := aArray[i] = aSrc;
inc(i);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
LSrc : String;
begin
LSrc := THashMD5.GetHashString( intToStr(1) );
//if MatchStr( LSrc, FArray ) then Showmessage('Bulundu') else Showmessage('Maalesef.... ');
if SearchArray( LSrc, FArray ) then Showmessage('Bulundu') else Showmessage('Maalesef.... ');
end;
* Denemek isteyenler için
- MD5 string halindeki indexlenmiş haldeki 52 bin adet hash içeren text dosya linki için
/image_StringArray_52000.php)
- MD5 string halindeki indexlenmiş haldeki 5 milyon adet hash içeren text dosya linki için
/image_StringArray_52000.php)
* Bu dosya içerisinde 0 .. 519999 kadar string rakamların MD5 hash'ı alınmış ve MD5 hallerine göre sort edilmiş hallerini bulacaksınız.
herhangi bir rakamın MD5 hash halini yukarıdaki fornksiyonda arama yaptırabilirsiniz.
Örnekte 52K elemanlıda 12 sıçrama (satır sorgusu) + 5 sıralı sorgu = 17 sıralı sorguda bulundu. 1'den 52000'e kadar sıralı sorgudan kaç kar hızlı anlatabildim sanırım. ( 1ncide de olsa 519999 ncuda da olsa benzer sürede bulacaktır. Diğer türlü 1'de ilk denemede 51999'da sıra numaralı denemede buluyordu.
PHP Kod:
(Sıçra : 0) iBas:0 iSon:51999 / iOrta: 25999 / Aradaki Eleman Say : 52000
Daha küçük....
(Sıçra : 1) iBas:0 iSon:25998 / iOrta: 12999 / Aradaki Eleman Say : 25999
Daha BÜYÜK....
(Sıçra : 2) iBas:13000 iSon:25998 / iOrta: 19498 / Aradaki Eleman Say : 12999
Daha BÜYÜK....
(Sıçra : 3) iBas:19499 iSon:25998 / iOrta: 22747 / Aradaki Eleman Say : 6500
Daha küçük....
(Sıçra : 4) iBas:19499 iSon:22746 / iOrta: 21122 / Aradaki Eleman Say : 3248
Daha BÜYÜK....
(Sıçra : 5) iBas:21123 iSon:22746 / iOrta: 21933 / Aradaki Eleman Say : 1624
Daha BÜYÜK....
(Sıçra : 6) iBas:21934 iSon:22746 / iOrta: 22339 / Aradaki Eleman Say : 813
Daha küçük....
(Sıçra : 7) iBas:21934 iSon:22338 / iOrta: 22136 / Aradaki Eleman Say : 405
Daha BÜYÜK....
(Sıçra : 8) iBas:22137 iSon:22338 / iOrta: 22236 / Aradaki Eleman Say : 202
Daha BÜYÜK....
(Sıçra : 9) iBas:22237 iSon:22338 / iOrta: 22286 / Aradaki Eleman Say : 102
Daha BÜYÜK....
(Sıçra : 10) iBas:22287 iSon:22338 / iOrta: 22311 / Aradaki Eleman Say : 52
Daha küçük....
(Sıçra : 11) iBas:22287 iSon:22310 / iOrta: 22298 / Aradaki Eleman Say : 24
Daha küçük....
(Sıçra : 12) iBas:22287 iSon:22297 / iOrta: 22292 / Aradaki Eleman Say : 11
Daha BÜYÜK....
Arama yapmak için kalan eleman sayısı : 5

Bu örnek projenin kaynak kodları :
Uses System.Hash, System.StrUtils;
Var
FArray : Array of String;
procedure RandomFill( aCount: Integer );
var
i : Integer;
begin
if Length(FArray) > 0 then Finalize(FArray);
SetLength( FArray, aCount );
for i := low(FArray) to high(FArray)
do FArray[i] := THashMD5.GetHashString( IntToStr(i) );
end;
procedure SortArray;
var
LTemp : string;
i : Integer;
LAgain : Boolean;
begin
repeat
LAgain := False;
i := low(FArray);
repeat
if CompareStr( FArray[i], FArray[i+1]) > 0 then
begin
LTemp := FArray[i];
FArray[i] := FArray[i+1];
FArray[i+1] := LTemp;
LAgain := True;
end;
Inc(i);
until(i > High(FArray)-1 );
until(LAgain = False);
end;
procedure TForm1.Button1Click(Sender: TObject);
const
ArraySize = 52*1000; // 52K kayıt
var
LTextFile : TextFile;
LFilename : String;
i : Integer;
begin
LFilename := ExtractFilePath( ParamStr(0) ) + 'StringArray_' + IntToStr(ArraySize) + '.TXT';
if NOT FileExists(LFilename) then
begin
RandomFill( ArraySize );
SortArray();
AssignFile( LTextFile, LFilename );
try
ReWrite( LTextFile );
for i := Low(FArray) to High(FArray) do
WriteLn( LTextFile, FArray[i] );
finally
CloseFile(LTextFile);
end;
Showmessage('Sıralama ve doldurma tamam...');
end else begin
if Length(FArray) > 0 then Finalize(FArray);
SetLength( FArray, ArraySize );
AssignFile( LTextFile, LFilename );
Reset( LTextFile );
try
i := 0;
while NOT EOF(LTextFile) do
begin
ReadLn( LTextFile, FArray[i] );
inc(i);
end;
finally
CloseFile(LTextFile);
end;
Showmessage('Array doldurma tamam...');
end;
end;
function SearchArray( aSrc : String; const aArray: Array of String ): boolean;
const
MakulElemanSayisi = 10;
var
i, LSayac, idxBas, idxSon, iOrta : Integer;
LSicrama : Integer;
begin
Result := False;
idxBas := Low (aArray);
idxSon := High(aArray);
LSayac := High(aArray)+1;
iOrta := (idxSon - idxBas) div 2;
LSicrama := 0;
repeat
form1.memo1.lines.Add( Format('(Sıçra : %d) iBas:%d iSon:%d / iOrta: %d / Aradaki Eleman Say : %d', [ LSicrama, idxBas, idxSon, iOrta, LSayac ]) );
if aSrc > aArray[iOrta] then begin
form1.memo1.lines.Add( 'Daha BÜYÜK....' );
idxBas := iOrta+1;
//idxSon := Aynı...
iOrta := iOrta + (idxSon - idxBas) div 2;
LSayac := (idxSon - idxBas + 1);
end else
if aSrc < aArray[iOrta] then begin
form1.memo1.lines.Add( 'Daha küçük....' );
//idxBas := Aynı...
idxSon := iOrta -1;
iOrta := idxBas + (idxSon - idxBas) div 2;
LSayac := (idxSon - idxBas + 1);
end
else Result := True; // bulundu... :)
Inc(LSicrama);
until ( LSayac <= MakulElemanSayisi ) or Result;
form1.memo1.lines.Add( Format(' Arama yapmak için kalan eleman sayısı : %d', [ LSayac ]) );
i := idxBas;
while (not result) AND (i <= idxSon) do begin
Result := aArray[i] = aSrc;
inc(i);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
LSrc : String;
begin
Memo1.Lines.Clear;
LSrc := THashMD5.GetHashString( intToStr(51999) );
//if MatchStr( LSrc, FArray ) then Showmessage('Bulundu') else Showmessage('Maalesef.... ');
if SearchArray( LSrc, FArray ) then Showmessage('Bulundu') else Showmessage('Maalesef.... ');
end;