Что нового

Использовать ContinueLoop или только If-Else?

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Я использую ContinueLoop (ExitLoop) в следующий случаях (очень удобно):

Код:
#Include <WinAPIEx.au3>

Global $tData = DllStructCreate('wchar[260]')

Do
	$hKey = _WinAPI_RegOpenKey($HKEY_LOCAL_MACHINE, 'SOFTWARE\AutoIt v3\AutoIt', $KEY_QUERY_VALUE)
	If @error Then
		ExitLoop
	EndIf
	_WinAPI_RegQueryValue($hKey, 'InstallDir', $tData)
	If @error Then
		ExitLoop
	EndIf
	
	; Что-нибудь еще...
	
Until 1
If @error Then
	$Msg = 'Error: ' & _WinAPI_GetLastErrorMessage()
Else
	$Msg = DllStructGetData($tData, 1)
EndIf
_WinAPI_RegCloseKey($hKey)

ConsoleWrite($Msg & @CR)


"ElseIf" вообще не использую, т.к. его можно заменить на

Код:
If ... Then
Else
	If ... Then
	EndIf
EndIf


Но, в отличии от последней конструкции, "ElseIf" сильно портит вид самого кода, IMHO лесенка намного читабельнее. В пользу "ContinueLoop" могу сказать, что он в 2 раза быстрее "ElseIf" и в 4 "Else If":

Код:
$Count = 0
$Timer = TimerInit()
For $i = 1 To 100000
	$Error = 6
	If $Error = 1 Then
	ElseIf $Error = 2 Then
	ElseIf $Error = 3 Then
	ElseIf $Error = 4 Then
	ElseIf $Error = 5 Then
	Else
		$Count += 1
	EndIf
Next
ConsoleWrite(TimerDiff($Timer) & @CR)

$Count = 0
$Timer = TimerInit()
For $i = 1 To 100000
	$Error = 6
	If $Error = 1 Then
	Else
		If $Error = 2 Then
		Else
			If $Error = 3 Then
			Else
				If $Error = 4 Then
				Else
					If $Error = 5 Then
					Else
						$Count += 1
					EndIf
				EndIf
			EndIf
		EndIf
	EndIf
Next
ConsoleWrite(TimerDiff($Timer) & @CR)

$Count = 0
$Timer = TimerInit()
For $i = 1 To 100000
	$Error = 6
	Switch $Error
		Case 1, 2, 3, 4, 5
			ContinueLoop
	EndSwitch
	$Count += 1
Next
ConsoleWrite(TimerDiff($Timer) & @CR)


С другой стороны, в машинном коде все равно нет особой разницы между всеми этими конструкциями, т.к. все происходит с помощью тех же операторов перехода J...
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Тоже заинтересовала скорость работы разных операторов при одинаковых условиях. :smile:
Код:
$iV = 10
$j = 0

$iStart = TimerInit()
While 1
	For $i = 1 To 5
		Switch $i
			Case 1
				$iV = $iV * 10
			Case 2
				$iV = $iV * 100
			Case 3
				$iV = $iV * 1000
			Case 4
				$iV = $iV * 2000
			Case Else
				$iV = $iV * 3000
		EndSwitch
	Next
	$j += 1
	If $j = 100000 Then ExitLoop
WEnd
$iTime = StringFormat('%.2f sec.', TimerDiff($iStart) / 1000)
MsgBox(0, $j, $iTime)

Код:
$iV = 10
$j = 0

$iStart = TimerInit()
While 1
	For $i = 1 To 5
		If $i = 1 Then
			$iV = $iV * 10
		ElseIf $i = 2 Then
			$iV = $iV * 100
		ElseIf $i = 3 Then
			$iV = $iV * 1000
		ElseIf $i = 4 Then
			$iV = $iV * 2000
		Else
			$iV = $iV * 3000
		EndIf
	Next
	$j += 1
	If $j = 100000 Then ExitLoop
WEnd
$iTime = StringFormat('%.2f sec.', TimerDiff($iStart) / 1000)
MsgBox(0, $j, $iTime)

Код:
$iV = 10
$j = 0

$iStart = TimerInit()
While 1
	For $i = 1 To 5
		Select
			Case $i = 1
				$iV = $iV * 10
			Case $i = 2
				$iV = $iV * 100
			Case $i = 3
				$iV = $iV * 1000
			Case $i = 4
				$iV = $iV * 2000
			Case Else
				$iV = $iV * 3000
		EndSelect
	Next
	$j += 1
	If $j = 100000 Then ExitLoop
WEnd
$iTime = StringFormat('%.2f sec.', TimerDiff($iStart) / 1000)
MsgBox(0, $j, $iTime)

Код:
$iV = 10
$j = 0

$iStart = TimerInit()
While 1
	For $i = 1 To 5
		If $i = 1 Then
			$iV = $iV * 10
		Else
			If $i = 2 Then
				$iV = $iV * 100
			Else
				If $i = 3 Then
					$iV = $iV * 1000
				Else
					If $i = 4 Then
						$iV = $iV * 2000
					Else
						$iV = $iV * 3000
					EndIf
				EndIf
			EndIf
		EndIf
	Next
	$j += 1
	If $j = 100000 Then ExitLoop
WEnd
$iTime = StringFormat('%.2f sec.', TimerDiff($iStart) / 1000)
MsgBox(0, $j, $iTime)

Скорость выполнения сильно отличается.
 

`p r o x y

«Улыбайтесь, господа!»
Команда форума
Глобальный модератор
Сообщения
596
Репутация
157
Это, довольно синтетические тесты. Уверен, что в зависимости от ситуации каждый из вариантов может «выиграть». Обсуждение же началось с удобства чтения такого кода. И тут очень хороший наглядный пример «древовидного» вариант пример № 4 и остальных.
 

`p r o x y

«Улыбайтесь, господа!»
Команда форума
Глобальный модератор
Сообщения
596
Репутация
157
Хммм...в общем, пишу функцию. Пишу-пишу, расширяю-расширяю, улучшаю, модифицирую, оптимизирую. В результате, вышло хорошо, работает правильно, но выглядит громоздко-громоздко. Посидел, подумал, попил чаю, перебрал заново. Вышло лучше, но не намного. В коде встречались несколько ContinueLoop, решил попробовать без них. Перекроил все, целиком и полностью с нуля, выкинул все ContinueLoop и один цикл, нашел новые пути оптимизации – функция уменьшилась в два раза, работает правильно. Однако, If-Else бывает эффективнее. Жалко первоначального варианта не сохранилось…
 
Верх