Сравниваю скорости нескольких функций, достигающих одного результата, разными способами. И с удивлением наблюдаю, как первая, работает медленнее других в одном проходе, но быстрее, при множественном. Буду рад, если, кто-то сможет пояснить такое отличие?
Пример:
Пример:
Код:
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <WinApi.au3>
#include <Array.au3>
__GUI_TestTime()
; переменные для тестируемых функций
Global $igW = 20, $igH = 20, $igTW = 100, $igMH = 100, $igHA = 1, $igVA = 1, $agP1, $agP2
; добавляем функции для тестирования. Вместо 5 следующих строк, можно так: Global $agTestFunctions_TSTM = ['Func1','Func2', 'Func3', 'Func4', 'Func5']
Add_Func_TestTime('Func1')
Add_Func_TestTime('Func2')
Add_Func_TestTime('Func3')
Add_Func_TestTime('Func4')
Add_Func_TestTime('Func5')
Start_TestTime() ; стартуем тест
#Region ТЕСТИРУЕМЫЕ ФУНКЦИИ
; ===============================================================================================================================
Func Func1()
$agP1 = $igHA = 1 ? ($igTW / 2) - ($igW / 2) : ($igHA = 2 ? $igTW - $igW : 0)
$agP2 = $igVA = 1 ? ($igMH / 2) - ($igH / 2) : ($igVA = 2 ? $igMH - $igH : 0)
EndFunc ;==>Func1
; ===============================================================================================================================
Func Func2()
If $igHA = 1 Then $agP1 = ($igTW / 2) - ($igW / 2)
If $igHA = 2 Then $agP1 = $igTW - $igW
If $igVA = 1 Then $agP2 = ($igMH / 2) - ($igH / 2)
If $igVA = 2 Then $agP2 = $igMH - $igH
EndFunc ;==>Func2
; ===============================================================================================================================
Func Func3()
If $igHA = 1 Then
$agP1 = ($igTW / 2) - ($igW / 2)
ElseIf $igHA = 2 Then
$agP1 = $igTW - $igW
EndIf
If $igVA = 1 Then
$agP2 = ($igMH / 2) - ($igH / 2)
ElseIf $igHA = 2 Then
$agP2 = $igMH - $igH
EndIf
EndFunc ;==>Func3
; ===============================================================================================================================
Func Func4()
Switch $igHA
Case 1
$agP1 = ($igTW / 2) - ($igW / 2)
Case 2
$agP1 = $igTW - $igW
EndSwitch
Switch $igVA
Case 1
$agP2 = ($igMH / 2) - ($igH / 2)
Case 2
$agP2 = $igMH - $igH
EndSwitch
EndFunc ;==>Func4
; ===============================================================================================================================
Func Func5()
Select
Case $igHA = 1
$agP1 = ($igTW / 2) - ($igW / 2)
Case $igHA = 2
$agP1 = $igTW - $igW
EndSelect
Select
Case $igVA = 1
$agP2 = ($igMH / 2) - ($igH / 2)
Case $igVA = 2
$agP2 = $igMH - $igH
EndSelect
EndFunc ;==>Func5
; ===============================================================================================================================
#EndRegion ТЕСТИРУЕМЫЕ ФУНКЦИИ
Local $iGUIMsg_TSTM
While 1
$iGUIMsg_TSTM = GUIGetMsg()
Switch $iGUIMsg_TSTM
Case $GUI_EVENT_CLOSE
ExitLoop
Case $igButRepeat_TSTM
GUICtrlSetState($igButRepeat_TSTM, $GUI_DISABLE)
Local $hLastChildForm_TSTM = 0
If $hgChildForm_TSTM Then $hLastChildForm_TSTM = $hgChildForm_TSTM
$hgChildForm_TSTM = __CreateChildForm_TestTime($hgForm_TSTM, 0x9AAFDC)
Start_TestTime($agTestFunctions_TSTM)
GUISetState(@SW_SHOW, $hgChildForm_TSTM)
If $hLastChildForm_TSTM Then GUIDelete($hLastChildForm_TSTM)
EndSwitch
WEnd
; #ПОЛЬЗОВАТЕЛЬСКАЯ_ФУНКЦИЯ# ====================================================================================================
; Описание ...: Добавляет функцию в список тестируемых
; Параметры ..: $sFuncName - Ммя функции
; Возвращает .: 1 - функция добавлена, 0 и @error - не добавлена
; ===============================================================================================================================
Func Add_Func_TestTime($sFuncName)
Call($sFuncName)
If @error = 0xDEAD And @extended = 0xBEEF Then
MsgBox(48, 'Тест времени функций', 'Функция «' & $sFuncName & '» не добавлена в список тестирования, так как не найдена' & @CRLF)
Return SetError(1, 0, 0)
EndIf
Local $iUB = UBound($agTestFunctions_TSTM)
ReDim $agTestFunctions_TSTM[$iUB + 1]
$agTestFunctions_TSTM[$iUB] = $sFuncName
Return 1
EndFunc ;==>Add_Func_TestTime
; #ПОЛЬЗОВАТЕЛЬСКАЯ_ФУНКЦИЯ# ====================================================================================================
; Описание ...: Удаляет функцию из списка тестируемых
; Параметры ..: $sFuncName - Ммя функции
; Возвращает .: 1 - функция удалена, 0 и @error - не удалена,
; ===============================================================================================================================
Func Del_Func_TestTime($sFuncName)
If Not UBound($agTestFunctions_TSTM) Then Return SetError(1, 0, 0)
Local $iInd = _ArraySearch($agTestFunctions_TSTM, $sFuncName)
If @error Then Return SetError(2, 0, 0)
_ArrayDelete($agTestFunctions_TSTM, $iInd)
If @error Then Return SetError(3, 0, 0)
Return 1
EndFunc ;==>Del_Func_TestTime
; #ПОЛЬЗОВАТЕЛЬСКАЯ_ФУНКЦИЯ# ====================================================================================================
; Описание ...: Стартует тестирование времени выполнения функций
; Параметры ..: $aCicles - массив, с количеством проходов (не обязательный, по умолчанию - [1, 2, 5, 10, 50, 100, 1000, 10000])
; ===============================================================================================================================
Func Start_TestTime($aCicles = 0)
Global $igMainCols_TSTM = 3 ; количество колонок
Global $igNumberDecimalPlaces_TSTM = 5 ; количество цифр, после запятой в результатах таймингов
If Not $aCicles Then Dim $aCicles = [1, 2, 5, 10, 50, 100, 1000, 10000] ; проверка на разном количестве проходов
GUICtrlSetData($igLabEvent_TSTM, 'Идёт тестирование...')
Global $igCiclElem
Local $iUBC = UBound($aCicles)
Local $iUB = UBound($agTestFunctions_TSTM)
Local $aTimeRes[$iUBC][$iUB], $aFnTimes[$iUB], $aMaxMin[$iUBC][2]
For $n = 0 To $iUBC - 1
$igCiclElem = $aCicles[$n] - 1
If $igCiclElem < 0 Then $igCiclElem = 0
Local $iTimeT
For $c = 0 To $iUB - 1
$iTimeT = __Caller_TestTime($agTestFunctions_TSTM[$c])
$aTimeRes[$n][$c] = $iTimeT
$aFnTimes[$c] = $iTimeT
Next
$aMaxMin[$n][0] = _ArrayMax($aFnTimes, 1)
$aMaxMin[$n][1] = _ArrayMin($aFnTimes, 1)
Next
__Redraw_TestTime($aTimeRes, $aMaxMin, $aCicles)
EndFunc ;==>Start_TestTime
; #СИСТЕМНАЯ_ФУНКЦИЯ# ===========================================================================================================
; Описание ...: Рисует графики протестированных функций
; ===============================================================================================================================
Func __Redraw_TestTime($aTimeRes, $aMaxMin, $aCicles)
Local $iPaddingX = 8, $iPaddingY = 8
Local $iSpaceLineW = 8, $iSpaceLineH = 8, $iTitleH = 14, $iFuncNameH = 14
Local $nY = 0, $iLineY, $iTitleX, $iTitleY, $iTitleW = 0, $iGraphDiap, $iTimeDiap, $iGraphW, $iGrpX = $iPaddingX, $iGrpH
Local $iGraphColor, $iRW, $iRowW = 0, $iRowH = 0
Local $iFuncTime, $iCicles, $iTitle, $iLbTime, $iFuncName
Local $hLastForm = GUISwitch($hgChildForm_TSTM)
Local $iGraph = GUICtrlCreateGraphic(0, 0, $igFormW_TSTM, $igFormH_TSTM - 25)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
Local $iUBC = UBound($aCicles)
Local $iUB = UBound($agTestFunctions_TSTM)
For $n = 0 To $iUBC - 1
$iLineY = $iUB = 1 ? $iPaddingY + $nY * ($iFuncNameH + $iSpaceLineH + $iTitleH + $iTitleH) - $igGraphH_TSTM + $iTitleH : $iPaddingY + $nY * ($igGraphH_TSTM + $iFuncNameH + $iSpaceLineH + $iTitleH)
$iTitleX = $iGrpX
$iTitleW = 0
$iGraphDiap = ($igGraphH_TSTM - $iTitleH) ; $igGraphH_TSTM-$iTitleH ; dMax - dMin
$iTimeDiap = $aMaxMin[$n][0] - $aMaxMin[$n][1]
$iCicles = $aCicles[$n]
$sClTitle = $iCicles & ' проход' & __DeclRusNumber_TestTime($iCicles, '', 'а', 'ов')
For $c = 0 To $iUB - 1
$sFuncTime = String($aTimeRes[$n][$c])
$iGraphW = __GetStringDimensions_TestTime($hgChildForm_TSTM, $sFuncTime)
If $iUB = 1 Then
$iClTitle = __GetStringDimensions_TestTime($hgChildForm_TSTM, $sClTitle)
If $iClTitle > $iGraphW Then $iGraphW = $iClTitle
EndIf
$iGrpH = $iUB = 1 ? $iTitleH : $iTitleH + ($iGraphDiap * ($aTimeRes[$n][$c] - $aMaxMin[$n][1])) / $iTimeDiap
$iGraphColor = $iUB = 1 ? 0x55FF4F : Ceiling(0x55FF4F + ((0xFF4D4D - 0x55FF4F) * ($aTimeRes[$n][$c] - $aMaxMin[$n][1])) / $iTimeDiap)
GUICtrlSetGraphic($iGraph, $GUI_GR_COLOR, 0x000000, $iGraphColor)
GUICtrlSetGraphic($iGraph, $GUI_GR_RECT, $iGrpX, $iLineY + $igGraphH_TSTM, $iGraphW, -$iGrpH)
$iLbTime = GUICtrlCreateLabel($sFuncTime, $iGrpX, $iLineY + $igGraphH_TSTM - $iGrpH, $iGraphW, $iTitleH, $SS_CENTER)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetBkColor(-1, -2)
GUICtrlSetFont(-1, 8)
$iFuncName = __CreateBorderLabel_TestTime($agTestFunctions_TSTM[$c], $iGrpX, $iLineY + $igGraphH_TSTM - 1, $iGraphW, $iFuncNameH, 0x0, 1, BitOR($SS_CENTER, $SS_CENTERIMAGE))
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetBkColor(-1, 0xFF8080)
GUICtrlSetFont(-1, 8)
$iGrpX += $iGraphW - 1
$iTitleW += $iGraphW - 1
Next
$iTitleY = $iLineY + $igGraphH_TSTM + $iFuncNameH - 2
$iTitle = __CreateBorderLabel_TestTime($sClTitle, $iTitleX, $iTitleY, $iTitleW + 1, $iTitleH, 0x0, 1, BitOR($SS_CENTER, $SS_CENTERIMAGE))
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetBkColor(-1, 0x80FF80)
GUICtrlSetFont(-1, 8)
$iGrpX += $iSpaceLineW
$iRW = $iTitleX + $iTitleW + 1
If $iRowW <= $iRW Then $iRowW = $iRW
If Mod($n, $igMainCols_TSTM) = $igMainCols_TSTM - 1 Then
$nY += 1
$iGrpX = $iPaddingX
$iTitleW = $iPaddingX
EndIf
Next
$iRowW += 6 + $iPaddingX
$iRowH = 66 + $iTitleY + $iTitleH
WinMove($hgForm_TSTM, '', (@DesktopWidth / 2) - ($iRowW / 2), (@DesktopHeight / 2) - ($iRowH / 2), $iRowW, $iRowH)
WinMove($hgChildForm_TSTM, '', 0, 30, $iRowW, $iRowH)
GUICtrlSetData($igLabEvent_TSTM, '')
GUICtrlSetState($igButRepeat_TSTM, $GUI_ENABLE)
GUISetState(@SW_SHOW, $hgChildForm_TSTM)
GUISetState(@SW_SHOW, $hgForm_TSTM)
EndFunc ;==>__Redraw_TestTime
; #СИСТЕМНАЯ_ФУНКЦИЯ# ===========================================================================================================
; Описание ...: Создаёт дочернюю форму
; ===============================================================================================================================
Func __CreateChildForm_TestTime($hParentForm, $iColor = -1)
Local $hFormChild = GUICreate('', $igFormW_TSTM, $igFormH_TSTM - 30, 0, 30, $WS_CHILD, $WS_EX_TOPMOST, $hParentForm)
GUICtrlSetResizing($hFormChild, $GUI_DOCKALL)
If $iColor >= 0 Then GUISetBkColor($iColor, $hFormChild)
Return $hFormChild
EndFunc ;==>__CreateChildForm_TestTime
; #СИСТЕМНАЯ_ФУНКЦИЯ# ===========================================================================================================
; Описание ...: Непосредственное тестирование
; ===============================================================================================================================
Func __Caller_TestTime($sFunc)
Local $iTimer, $iTime
$iTimer = TimerInit()
For $i = 0 To $igCiclElem
Call($sFunc)
Next
$iTime = TimerDiff($iTimer)
Return StringFormat('%.' & String($igNumberDecimalPlaces_TSTM) & 'f', $iTime)
EndFunc ;==>__Caller_TestTime
; #СИСТЕМНАЯ_ФУНКЦИЯ# ===========================================================================================================
; Описание ...: Создание интерфейса
; ===============================================================================================================================
Func __GUI_TestTime()
Global $agTestFunctions_TSTM[0]
Global $igGraphH_TSTM = 50
Global $hgForm_TSTM, $hgChildForm_TSTM
Global $igFormW_TSTM = 333, $igFormH_TSTM = 200
Global $hgForm_TSTM = GUICreate('Тест времени функций', $igFormW_TSTM, $igFormH_TSTM, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU))
Global $igButRepeat_TSTM = GUICtrlCreateButton('Обновить', 4, 2, 80, 24, BitOR($BS_CENTER, $BS_VCENTER))
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetImage(-1, "C:\Windows\System32\shell32.dll", -138, 0)
GUICtrlSetTip(-1, 'Старт теста')
GUICtrlSetState(-1, $GUI_DISABLE)
Global $igLabEvent_TSTM = GUICtrlCreateLabel('', 88, 2, 150, 24, BitOR($BS_CENTER, $BS_VCENTER))
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 8, 800)
GUISetBkColor(0x88AABB)
Global $hgChildForm_TSTM = __CreateChildForm_TestTime($hgForm_TSTM, 0x9AAFDC)
;~ GUISetState(@SW_SHOW, $hgForm_TSTM)
EndFunc ;==>__GUI_TestTime
; #СИСТЕМНАЯ_ФУНКЦИЯ# ===========================================================================================================
; Описание ...: Склоняет русские слова, относительно чисел
; ===============================================================================================================================
Func __DeclRusNumber_TestTime($iN, $sT1, $sT2, $sT3)
Return (Mod($iN, 10) = 1 And Mod($iN, 100) <> 11) ? $sT1 : (Mod($iN, 10) >= 2 And Mod($iN, 10) <= 4 And (Mod($iN, 100) < 10 Or Mod($iN, 100) >= 20)) ? $sT2 : $sT3
EndFunc ;==>__DeclRusNumber_TestTime
; #СИСТЕМНАЯ_ФУНКЦИЯ# ===========================================================================================================
; Описание ...: Определяет длину строки в пикселях
; ===============================================================================================================================
Func __GetStringDimensions_TestTime($hWnd, $sText)
Local $hDC = _WinAPI_GetDC($hWnd)
Local $hFont = _SendMessage($hWnd, 0x0031)
Local $hSelectObject = _WinAPI_SelectObject($hDC, $hFont)
Local $tSIZE = _WinAPI_GetTextExtentPoint32($hDC, $sText)
_WinAPI_SelectObject($hDC, $hSelectObject)
_WinAPI_ReleaseDC($hWnd, $hDC)
Return DllStructGetData($tSIZE, 1)
EndFunc ;==>__GetStringDimensions_TestTime
; #СИСТЕМНАЯ_ФУНКЦИЯ# ===========================================================================================================
; Описание ...: Рисует Label с рамкой нужного цвета
; ===============================================================================================================================
Func __CreateBorderLabel_TestTime($sText, $iX, $iY, $iW, $iH, $iColor, $iPenSize = 1, $iStyle = -1, $iStyleEx = 0)
GUICtrlCreateLabel('', $iX, $iY, $iW, $iH, 0)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetBkColor(-1, $iColor)
Return GUICtrlCreateLabel($sText, $iX + $iPenSize, $iY + $iPenSize, $iW - 2 * $iPenSize, $iH - 2 * $iPenSize, $iStyle, $iStyleEx)
EndFunc ;==>__CreateBorderLabel_TestTime
Последнее редактирование: