Voici le projet de mesure de temps : Test.Perf.const.param.zip
A la base, juste vérifier entre le FastMM intégré dans Delphi 10 Sealte vs NexusMM en 64Bits uniquement quelques modifications de code
Et ayant un nouveau code à appréhender, je note quelques optimisations comme le const sur les string en paramètre qui évite la copie pour améliorer le projet que je dois maintenant maintenir
Le phénomène que j'observe et qui m'emmerde particulièrement pour mesurer des variantes plus ou moins rapides d'une fonction est qu'en lançant plusieurs fois de suite la même boucle autour d'une fonction, cela va de plus en plus vite.
Parfois c'est moins marqué mais j'ai quand même très souvent, cette forme de temps décroissant
A chaque clic, cela repart sur un temps de base puis ça décroit (pas toujours)
Comment savoir ce qui fonctionne vraiment plus vite si cela dépend de l'humeur du CPU à l'instant T (est-ce qu'un très grand nombre de répétition peut niveler cela, mais je vais pas attendre des heures pour savoir si ma modification est pertinente ou pas)
Essai en FastMM, une seule instance, trois clic consecutifs
Premier Clic
la secondeCompare Param Const && Copy : x 1000000 / Len = 10 = 1234567890
Const : 00:00:00:009
Copy : 00:00:00:086
Const 2 : 00:00:00:009
Copy 2 : 00:00:00:086
Txxx_EncodeSendText : 00:00:02:765
Txxx_EncodeSendText 2 : 00:00:01:660
Txxx_EncodeSendText 3 : 00:00:01:288
Txxx_EncodeSendText 4 : 00:00:01:091
La troisièmeCompare Param Const && Copy : x 1000000 / Len = 10 = 1234567890
Const : 00:00:00:009
Copy : 00:00:00:086
Const 2 : 00:00:00:009
Copy 2 : 00:00:00:086
Txxx_EncodeSendText : 00:00:02:643
Txxx_EncodeSendText 2 : 00:00:01:623
Txxx_EncodeSendText 3 : 00:00:02:525
Txxx_EncodeSendText 4 : 00:00:02:032
Compare Param Const && Copy : x 1000000 / Len = 10 = 1234567890
Const : 00:00:00:010
Copy : 00:00:00:089
Const 2 : 00:00:00:009
Copy 2 : 00:00:00:086
Txxx_EncodeSendText : 00:00:02:450
Txxx_EncodeSendText 2 : 00:00:01:568
Txxx_EncodeSendText 3 : 00:00:01:247
Txxx_EncodeSendText 4 : 00:00:02:538
J'ai essayé différente façon de l'écrire, comme mettre le code à tester dans une sous-fonction, toujours ce phénomène
Il est donc impossible de savoir si c'est le hasard de tomber sur une bonne humeur du CPU si l'on enchaine une version A puis une B puisque entre A et A, il y a des une différence
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 procedure TTestPerfConstParamMainForm.btnCompareConstOrCopyClick(Sender: TObject); var Laps: TLaps; procedure AddLap(const ATitle: string; ADelay: Int64); begin Laps.Add(ATitle, ADelay); MemoTimes.Lines.Add(Format('%s : %s', [ATitle, FormatMS(ADelay)])); end; var Tick: Int64; Lap: TLap; LapArray: TArray<TLap>; LapKeeper: TLapKeeper; SL: TStringList; procedure Test_CallConstString(const S: string; const ATitle: string); var I: Integer; begin GetBeginTime(Tick); for I := 1 to 1000 * TrackBarRepetition.Position do CallConstString(S); AddLap(ATitle, ElapsedTime(Tick)); end; procedure Test_CallCopyString(const S: string; const ATitle: string); var I: Integer; begin GetBeginTime(Tick); for I := 1 to 1000 * TrackBarRepetition.Position do CallCopyString(S); AddLap(ATitle, ElapsedTime(Tick)); end; procedure Test_TxxxBaseServerSocket_EncodeSendText(const S: string; const ATitle: string); var I: Integer; S3: string; begin GetBeginTime(Tick); for I := 1 to 1000 * TrackBarRepetition.Position do S3 := TxxxBaseServerSocket_EncodeSendText(S); AddLap(ATitle, ElapsedTime(Tick)); end; var I: Integer; S, S2: string; begin Laps := TLaps.Create(); try MemoTimes.Lines.Clear(); for I := 1 to TrackBarStringSize.Position do S := S + Chr(Ord('0') + I mod 10); S2 := S; MemoTimes.Lines.Add(Format('%s : x %d / Len = %d = %s', [TButton(Sender).Caption, 1000 * TrackBarRepetition.Position, TrackBarStringSize.Position, S])); MemoTimes.Refresh(); Test_CallConstString(S2, 'Const'); Test_CallCopyString(S2, 'Copy'); Test_CallConstString(S2, 'Const 2'); Test_CallCopyString(S2, 'Copy 2'); Test_TxxxBaseServerSocket_EncodeSendText(S2, 'TxxxBaseServerSocket_EncodeSendText'); Test_TxxxBaseServerSocket_EncodeSendText(S2, 'TxxxBaseServerSocket_EncodeSendText 2'); Test_TxxxBaseServerSocket_EncodeSendText(S2, 'TxxxBaseServerSocket_EncodeSendText 3'); Test_TxxxBaseServerSocket_EncodeSendText(S2, 'TxxxBaseServerSocket_EncodeSendText 4'); MemoTimes.Lines.Add(TButton(Sender).Caption + ' - Classement'); LapArray := Laps.ToArray(); TArray.Sort<TLap>(LapArray, TLapComparer.Create()); for Lap in LapArray do begin MemoTimes.Lines.Add(Format('%s : %s', [Lap.Key, FormatMS(Lap.Value)])); vleTimes.Values[Lap.Key] := IntToStr(Lap.Value); I := vleTimes.Strings.IndexOfName(Lap.Key); LapKeeper := TLapKeeper(vleTimes.Strings.Objects[I]); if not Assigned(LapKeeper) then begin LapKeeper := TLapKeeper.Create(); vleTimes.Strings.Objects[I] := LapKeeper; end; vleTimes.Values[Lap.Key] := vleTimes.Values[Lap.Key] + ' | ' + FormatMS(LapKeeper.Add(Lap.Value)); end; SL := TStringList.Create(); try SL.AddStrings(vleTimes.Strings); SL.CustomSort(TLapKeeper.CompareForCustomSort); vleTimes.Strings := SL; finally SL.Free(); end; finally Laps.Free(); end; end;
En Nexus, ce test est mortel mais est-ce vrai ?
Compare Param Const && Copy : x 1000000 / Len = 10 = 1234567890
Const : 00:00:00:004
Copy : 00:00:00:058
Const 2 : 00:00:00:004
Copy 2 : 00:00:00:056
TxxxBaseServerSocket_EncodeSendText : 00:00:05:623
TxxxBaseServerSocket_EncodeSendText 2 : 00:00:04:894
TxxxBaseServerSocket_EncodeSendText 3 : 00:00:05:792
TxxxBaseServerSocket_EncodeSendText 4 : 00:00:07:161
Comment expliquer ces temps si variable pour le même code lancé de façon rapproché
Partager