Page 1 sur 1

[..] Benchmark, boucle et variable

Posté : mar. 18 janv. 2022 12:28
par jpascal
Bonjour,

J'ai voulu comparer trois façons de coder.
Je génère un tableau contenant des nombres.
Pour chaque test, je récupère toutes les valeurs de la xème colonne pour :
- action A : ajouter à une string avec un séparateur |
- action B : ajouter à un tableau

- Test 1
action A dans une boucle
action B dans une autre boucle

- Test 2
actions A et B dans la même boucle

- Test 3
dans une même boucle :
la valeur de la xème colonne est d'abord stockée dans une variable
actions A et B en utilisant la variable

Pour chaque test, je mesure sa durée et j'exclue le résultat si elle diffère de 15% de la moyenne des résultats de ce test.

La méthode 2 semble prendre plus de temps, ce qui me semble illogique.
Et impossible de savoir si la méthode 3 est meilleure que la 1.

Pouvez-vous me dire si ma façon de procéder est valide ?

Résultats :
Test1|4383|874
Test1|4834|881
Test3|4849|873
Test3|4853|878
Test1|4855|846
Test2|4856|862
Test3|4861|873
Test3|4868|895
Test2|4872|871
Test2|4880|876
Test2|4882|865
Test3|4898|859
Test2|4900|864
Test1|4902|867
Test1|4918|858

#include <Array.au3>
#include <Debug.au3>

Global $g_iMaxErrorRate = 0.15  ; 15 % d'erreur maximum
Global $g_iColumns = 9
Global $g_aData[0][$g_iColumns]
Global $g_aAllTimes[0][3]
Global $g_aExtract[0]

CreateData()
;~ _ArrayDisplay($g_aData)
For $i = 1 To 5
   Tests('Test1')
   Tests('Test2')
   Tests('Test3')
;~    Tests('Test4')
Next
_DebugArrayDisplay($g_aAllTimes, 'Résultats', '', $ARRAYDISPLAY_NOROW, Default, 'Test|Temps|Essais')


Func Tests($sFunc)
   Local $aResult[0]
   Local $iTotalTry = 1000
   Local $iTotalTime = 0, $iTime = 0
   Local $iResults = 0 ; nombre de résultats "cohérents"

   For $i = 1 To $iTotalTry ; même algo
      $iTime = Call($sFunc)
;~       ConsoleWrite($iTime & @CRLF)
      _ArrayAdd($aResult, $iTime)
      $iTotalTime += $iTime
   Next
;~    _ArrayDisplay($aResult)
   $iAvgDuration = $iTotalTime / $iTotalTry ; temps moyen

   $iMaxDiff = $iAvgDuration * $g_iMaxErrorRate

   ; Suppression des résultats "incohérents"
   $iTotalTime = 0
   For $i = 0 To UBound($aResult) - 1
      If $aResult[$i] - $iAvgDuration < $iMaxDiff Then
         $iTotalTime += $aResult[$i]
         $iResults += 1
      Else
;~          ConsoleWrite("Temps de " &  $aResult[$i] & " sec supprimé des résultats" & @CRLF)
      EndIf
   Next

   _ArrayAdd($g_aAllTimes, $sFunc & '|' & Round($iTotalTime * 1000 / $iResults) & '|' & $iResults)
   ConsoleWrite($sFunc & " - Temps moyen pour " & $iResults & " / " & $iTotalTry & " essais : " & Round($iTotalTime * 1000 / $iResults) & " ms" & @CRLF)
EndFunc   ;==>Tests

Func Test1()
   Local $hTimer = TimerInit()
   Local $sList = ''
   ReDim $g_aExtract[0]

   For $i = 0 To UBound($g_aData) - 1
      $sList &= '|' & $g_aData[$i][$g_iColumns - 1]
   Next

   For $i = 0 To UBound($g_aData) - 1
      _ArrayAdd($g_aExtract, $g_aData[$i][$g_iColumns - 1]) ; valeur de la dernière colonne
   Next

   Return TimerDiff($hTimer)
EndFunc   ;==>Test1

Func Test2()
   Local $hTimer = TimerInit()
   Local $sList = ''
   ReDim $g_aExtract[0]

   For $i = 0 To UBound($g_aData) - 1
      $sList &= '|' & $g_aData[$i][$g_iColumns - 1]
      _ArrayAdd($g_aExtract, $g_aData[$i][$g_iColumns - 1]) ; valeur de la dernière colonne
   Next

   Return TimerDiff($hTimer)
EndFunc   ;==>Test2

Func Test3()
   Local $hTimer = TimerInit()
   Local $sList = ''
   Local $sData = ''
   ReDim $g_aExtract[0]

   For $i = 0 To UBound($g_aData) - 1
      $sData = $g_aData[$i][$g_iColumns - 1]
      $sList &= '|' & $sData
      _ArrayAdd($g_aExtract, $sData) ; valeur de la dernière colonne
   Next

   Return TimerDiff($hTimer)
EndFunc   ;==>Test3

Func Test4()
   Local $aList[0]
   Local $hTimer = TimerInit()
   Local $sList = ''
   Local $sData = ''
   ReDim $g_aExtract[0]

   For $i = 0 To UBound($g_aData) - 1
      $sData = $g_aData[$i][$g_iColumns - 1]
      _ArrayAdd($aList, $sData)
      _ArrayAdd($g_aExtract, $sData) ; valeur de la dernière colonne
   Next
   $sList = _ArrayToString($aList)

   Return TimerDiff($hTimer)
EndFunc   ;==>Test4

Func CreateData()
   Local $sLine = ''
   For $i = 0 To 100
      $sLine = ''
      For $iCol = 1 To $g_iColumns
         $sLine &= Random(1000000000, 9999999999, 1) & '|'
      Next
      $sLine = StringTrimRight($sLine, 1)
      _ArrayAdd($g_aData, $sLine)
   Next
EndFunc   ;==>CreateData

Re: [..] Benchmark, boucle et variable

Posté : mar. 18 janv. 2022 19:05
par mikell
La méthode est valide... et AMHA elle montre qu'entre les 3 tests effectués la différence n'est pas significative :wink:

Re: [..] Benchmark, boucle et variable

Posté : mar. 18 janv. 2022 23:47
par Faco
Bonsoir,

Code : Tout sélectionner

Func Test0()
   Local $hTimer = TimerInit()
   Local $sList = ''
   ReDim $g_aExtract[UBound($g_aData)] ;Redim de la bonne taille

   For $i = 0 To UBound($g_aData) - 1
      $sList &= '|' & $g_aData[$i][$g_iColumns - 1]
	  $g_aExtract[$i] = $g_aData[$i][$g_iColumns - 1] ;affectation plus efficace que _ArrayAdd
   Next

;~    For $i = 0 To UBound($g_aData) - 1
;~       _ArrayAdd($g_aExtract, $g_aData[$i][$g_iColumns - 1]) ; valeur de la dernière colonne
;~    Next

   Return TimerDiff($hTimer)
EndFunc   ;==>Test0
Résultats :
Test0 - Temps moyen pour 852 / 1000 essais : 1044 ms
Test1 - Temps moyen pour 931 / 1000 essais : 14196 ms
Test2 - Temps moyen pour 868 / 1000 essais : 14246 ms
Test3 - Temps moyen pour 941 / 1000 essais : 14064 ms

Re: [..] Benchmark, boucle et variable

Posté : mer. 19 janv. 2022 11:20
par jpascal
Merci mikell pour ta confirmation.

Et merci Faco pour la proposition. Même si en général je travaille sur des tableaux non dimensionnés, il est bon de se rappeler que cela a ses avantages. ;-)
Test1 - Temps moyen pour 834 / 1000 essais : 4526 ms
Test0 - Temps moyen pour 759 / 1000 essais : 265 ms
Test1 - Temps moyen pour 844 / 1000 essais : 4532 ms
Test0 - Temps moyen pour 861 / 1000 essais : 237 ms

Re: [..] Benchmark, boucle et variable

Posté : mer. 19 janv. 2022 15:12
par Faco
On a pas le même PC... :cry: :cry: :lol: