et avec le mien ??
et avec le mien ??
Salut vous tous.
J'aimerais dire avant toute chose que le code de Edam est le plus rapide.
J'ai retravaillé ma fonction pour m'approcher le plus possible de ses performances
mais il en m'en manque encore un peu.
J'ai l'impression que c'est l'utilisation de LastDelimiter() qui me pénalise.
voilà la methode de Edam (modifier pour en faire une fonction comparable)
À noter que j'ai ajouté un CloseFile...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 //== solution par Edam == function LastText(FileName:string):string; var f:file of byte; s,m:string; t,j:integer; b,bb:Boolean; Function Dechiffre:Boolean; var i,j:integer; n:string; begin n:=m; j:=length(m); i:=j; while (j>0) and (n[j]<>#10) do dec(j); result:=(j>0); if result then begin i:=i-j; setlength(m,i); inc(j); move(n[j],m[1],i); end; end; begin assignfile(f,FileName); {$i-} reset(f); if IOResult<>0 then exit; t:=filesize(f); s:=''; b:=false;bb:=false; repeat t:=t-$400; if t<0 then t:=0; seek(f,t); setlength(m,$400); BlockRead(f,m[1],$400,j); if not bb then begin while (j>0) and ((m[j]=#10) or (m[j]=#13)) do dec(j); bb:=j>0; end; if bb then begin if j<$400 then setlength(m,j); b:=Dechiffre; s:=m+s; end; until (b) or (t=0); CloseFile(f); // Ajout par EB result:=s; end;
Et Voici mon code retravaillé...simplifié...mieux écrit etc...
et ce pour tenter de rejoindre en vain les performances du code de Edam.
Les tests effectués sont les suivants:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 //============================================================================== //== Obtient la derniere Ligne d'un fichier texte. //== la derniere ligne doit être plus petite que 1022 caractères //== Option: SkipLastEmptyLine=TRUE //== Retourne alors l'avant dernière ligne si le fichier termine //== par un CRLF //== Une erreur : "I/0 error 103" arrive si le fichier n'existe pas. //== La fonction appelante doit donc faire la vérification de l'existance //== des fichiers. function GetLastLn(TextFileName:string;SkipLastEmptyLine:boolean=FALSE):string; const BUFF_SIZE=1024; CRLF= #13+#10; var size : Cardinal; f: file of byte; //Plus rapide que char! LastPosCRLF:Cardinal; TempStr:string; begin result:=''; SetLength(TempStr,BUFF_SIZE); AssignFile(f, TextFileName); try Reset(f); size := FileSize(f); if size<>0 then begin if size>BUFF_SIZE then Seek(f,size-BUFF_SIZE); BlockRead( f,TempStr[1],BUFF_SIZE,size); SetLength(TempStr,size); if (SkipLastEmptyLine=TRUE) and (strcomp(@TempStr[size-1],CRLF)=0) then TempStr:=Copy(TempStr,1,size-2); // Remove last CRLF if need LastPosCRLF:=LastDelimiter(CRLF,TempStr); if LastPosCRLF<>0 then result:=PChar(@TempStr[LastPosCRLF+1]) else result:=TempStr; end; finally CloseFile(f); end; end;
Fichier texte d'evirons 17Mb
Nombre d'appele: 100 000 fois
Delphi 5.
Score:
[Edam-File of Byte] 6.50 secondes
[EB-File of Byte] 6.56 secondes
[EB-avec TFileStream] 7.05 secondes
[Sub-0 TFileStream] 8.72 secondes
Mes Conclusions:
File of byte est plus rapide que File of Char.
File of Char est plus rapide que l'utilisation d'un TFileStream.
à noter que Ce sont là tous des codes très rapides si
on considère que ca prend 100 000 call pour en mesurer les
différences.
C'est vrai que le code pour faire la mesure n'est pas très précis
mais ca donne quand même une idée correcte des performances:
Finalement Edam
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 procedure TForm1.Button1Click(Sender: TObject); const NbrCall=100000; var lastLn1:string; lastLn2:string; lastLn3:string; lastLn4:string; TimeStart:TDateTime; TimeStop:TDateTime; i:integer; convert:extended; begin RichEdit1.Lines.Clear; convert:=60*60*24; TimeStart:=Now(); for i:=0 to NbrCall do lastLn1:=GetLastLn('C:\test.txt',FALSE); TimeStop:=Now(); RichEdit1.Lines.Add(lastLn1+'[EB-File of Byte] '+FormatFloat('0.00',(TimeStop-TimeStart)*convert)+' secondes'); self.Refresh; //Memcode sauf que j'utilise TFileStream TimeStart:=Now(); for i:=0 to NbrCall do lastLn2:=GetLastLn2('C:\test.txt',FALSE); TimeStop:=Now(); RichEdit1.Lines.Add(lastLn2+' [EB-TFileStream] '+FormatFloat('0.00',(TimeStop-TimeStart)*convert)+' secondes'); self.Refresh; TimeStart:=Now(); for i:=0 to NbrCall do lastLn3:=LastText('C:\test.txt'); TimeStop:=Now(); RichEdit1.Lines.Add(lastLn3+'[Edam] '+FormatFloat('0.00',(TimeStop-TimeStart)*convert)+' secondes'); self.Refresh; TimeStart:=Now(); for i:=0 to NbrCall do lastLn4:=GetLastRow('C:\test.txt'); TimeStop:=Now(); RichEdit1.Lines.Add(lastLn4+' [Sub-0] '+FormatFloat('0.00',(TimeStop-TimeStart)*convert)+' secondes'); self.Refresh; end;
Hallo,
edam, ne sois pas tu m'as fait aussi très plaisir en postant une solutions.
Le seul probleme que j'ai eu, c'était de ne pas avoir compris très bien ton code,
par example de mettre dans la function.
Je suis débutant et j'essaie de comprendre ce que je fait...(pas toujours!)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Function Dechiffre:Boolean; // ce si je n'ai pas compris!
En tout cas, j'ai un très grand respect à tous ceux qui poste pour aider les autres. Car dans ce monde on se fait pas toujours aider!
Croyez moi le plaisire que j'ai si j'ai une réponse à mon problème.
Salutations et très bon Weekend à tous.
Ardely
Dechiffre est une fonction (fonction privé à son conteneur "GetLastRow"; si j'ose dire ) dans la procedure où il est déclaré. c'est autorisé en delphi.
bien sûr je peut la déclaré dehor mais pour ne pas ajouté des pramétres à sa déclaration; en plus ij'en ai besoin que pour la Function GetLastRow
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 Function Dechiffre:Boolean; var i,j:integer; n:string; begin n:=m; j:=length(m); i:=j; while (j>0) and (n[j]<>#10) do dec(j); result:=(j>0); if result then begin i:=i-j; setlength(m,i); inc(j); move(n[j],m[1],i); end; end;
alors pour qoi tu n'as pas posé la questionEnvoyé par Ardely
ne somme tous passé par là sauf bilguiteEnvoyé par Ardely
tt le monde ici pour sa, donner et apprendreEnvoyé par Ardely
alors, pose tes questions (convenablement et aprés recherche) et ne quitte pas ton poste qu'aprés tt compris,, ok?Envoyé par Ardely
Hallo, Pour avancer et pour mieux comprendre pourrais-tu s.v.p me donné une petite explication de cette fonction qui est introduite dans la fonction 'LastText'
Merci et salutations
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Function Dechiffre:Boolean;
dans ma procedure je lis a partir de fin de fichier des bloc de $400 byte ; et ma function dechiffre ne fais que cherché si le caratére de fin de lin (lin qui précéde le dérnier) est touvé si non en lis un autre bloc et insi de suite et en cumule tout
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 Function Dechiffre:Boolean; var i,j:integer; n:string; begin n:=m; j:=length(m); i:=j; while (j>0) and (n[j]<>#10) do dec(j);// recherche de chr(10) à partir de la fin de string(n) result:=(j>0); if result then begin i:=i-j; setlength(m,i); inc(j); move(n[j],m[1],i); end; // si le trouve il coupie les caractére à partir de chr(10) trouvé jusqu'à la fin de string où en a cherché end;
bah je suis pas doué dans les explications mais j'éspére que sa suffira? si tu veux je détaille plus (même si ce sera une grand punition pour déposé un code )
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 b:=Dechiffre; s:=m+s;
La fonction Pos (ou AnsiPos) ne ferait-elle pas la même chose ?
[EDIT]
Ah non, je suis bête : Elle recherche la 1ère occurence... pas la dernière. Il faudrait alors faire une ReverseString() avant d'analyser la chaine, puis inverser le résultat :Bref, j'ai rien dis.
Code : Sélectionner tout - Visualiser dans une fenêtre à part Result := Abs(Pos(#10#13, ReverseString(str)) - Length(str));
à+
Ah, enfin, je viens de comprendre maintenant cette fonctionnalité dans une fonction. Maintenant je vois l'intérêt et le parcours à ce bon résultat,
Merci edam
pas de quoi
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager