An early exit can reduce unnecessary loop work when a condition has already been satisfied.

Program

Play the program to choose the target and compare how many checks the scan performs.

target
early_exit_scan.f90
Replay: real traced execution (multi-file project)
program early_exit_scan_demo
    implicit none
    integer :: values(5)
    integer :: target
    integer :: i
    integer :: checks
    integer :: found_at

    values = [3, 6, 9, 12, 15]
    target = 12
    checks = 0
    found_at = 0
    do i = 1, size(values)
        checks = checks + 1
        if (values(i) == target) then
            found_at = i
            exit
        end if
    end do
    print '(I0, 1X, I0)', found_at, checks
end program early_exit_scan_demo
program early_exit_scan_demo
    implicit none
    integer :: values(5)
    integer :: target
    integer :: i
    integer :: checks
    integer :: found_at

    values = [3, 6, 9, 12, 15]
    target = 6
    checks = 0
    found_at = 0
    do i = 1, size(values)
        checks = checks + 1
        if (values(i) == target) then
            found_at = i
            exit
        end if
    end do
    print '(I0, 1X, I0)', found_at, checks
end program early_exit_scan_demo
program early_exit_scan_demo
    implicit none
    integer :: values(5)
    integer :: target
    integer :: i
    integer :: checks
    integer :: found_at

    values = [3, 6, 9, 12, 15]
    target = 14
    checks = 0
    found_at = 0
    do i = 1, size(values)
        checks = checks + 1
        if (values(i) == target) then
            found_at = i
            exit
        end if
    end do
    print '(I0, 1X, I0)', found_at, checks
end program early_exit_scan_demo
  1. values ← [3, 6, 9, 12, 15]

    9values = [3, 6, 9, 12, 15]10target = 12
    values this step[3, 6, 9, 12, 15]values
  2. target ← 12

    9values = [3, 6, 9, 12, 15]10target = 1211checks = 0
    values this step12target
  3. checks ← 0

    10target = 1211checks = 012found_at = 0
    values this step0checks
  4. found_at ← 0

    11checks = 012found_at = 013do i = 1, size(values)
    values this step0found_at
  5. checks ← 1

    13do i = 1, size(values)14    checks = checks + 115    if (values(i) == target) then
    values this step0 1checks1i
  6. matched ← .false.

    14checks = checks + 115if (values(i) == target) then16    found_at = i
    values this step.false.matched3values(i)12target
  7. checks ← 2

    13do i = 1, size(values)14    checks = checks + 115    if (values(i) == target) then
    values this step1 2checks2i
  8. matched ← .false.

    14checks = checks + 115if (values(i) == target) then16    found_at = i
    values this step.false.matched6values(i)12target
  9. checks ← 3

    13do i = 1, size(values)14    checks = checks + 115    if (values(i) == target) then
    values this step2 3checks3i
  10. matched ← .false.

    14checks = checks + 115if (values(i) == target) then16    found_at = i
    values this step.false.matched9values(i)12target
  11. checks ← 4

    13do i = 1, size(values)14    checks = checks + 115    if (values(i) == target) then
    values this step3 4checks4i
  12. matched ← .true.

    14checks = checks + 115if (values(i) == target) then16    found_at = i
    values this step.true.matched12values(i)12target
  13. found_at ← 4

    15if (values(i) == target) then16    found_at = i17    exit
    values this step4found_at
  14. exit ← scan stops

    16    found_at = i17    exit18end if
    values this stepscan stopsexit
  15. print '(I0, 1X, I0)', found_at, checks

    19    end do20    print '(I0, 1X, I0)', found_at, checks21end program early_exit_scan_demo
    output4 4
    values this step4found_at4checks
  1. values ← [3, 6, 9, 12, 15]

    9values = [3, 6, 9, 12, 15]10target = 6
    values this step[3, 6, 9, 12, 15]values
  2. target ← 6

    9values = [3, 6, 9, 12, 15]10target = 611checks = 0
    values this step6target
  3. checks ← 0

    10target = 611checks = 012found_at = 0
    values this step0checks
  4. found_at ← 0

    11checks = 012found_at = 013do i = 1, size(values)
    values this step0found_at
  5. checks ← 1

    13do i = 1, size(values)14    checks = checks + 115    if (values(i) == target) then
    values this step0 1checks1i
  6. matched ← .false.

    14checks = checks + 115if (values(i) == target) then16    found_at = i
    values this step.false.matched3values(i)6target
  7. checks ← 2

    13do i = 1, size(values)14    checks = checks + 115    if (values(i) == target) then
    values this step1 2checks2i
  8. matched ← .true.

    14checks = checks + 115if (values(i) == target) then16    found_at = i
    values this step.true.matched6values(i)6target
  9. found_at ← 2

    15if (values(i) == target) then16    found_at = i17    exit
    values this step2found_at
  10. exit ← scan stops

    16    found_at = i17    exit18end if
    values this stepscan stopsexit
  11. print '(I0, 1X, I0)', found_at, checks

    19    end do20    print '(I0, 1X, I0)', found_at, checks21end program early_exit_scan_demo
    output2 2
    values this step2found_at2checks
  1. values ← [3, 6, 9, 12, 15]

    9values = [3, 6, 9, 12, 15]10target = 14
    values this step[3, 6, 9, 12, 15]values
  2. target ← 14

    9values = [3, 6, 9, 12, 15]10target = 1411checks = 0
    values this step14target
  3. checks ← 0

    10target = 1411checks = 012found_at = 0
    values this step0checks
  4. found_at ← 0

    11checks = 012found_at = 013do i = 1, size(values)
    values this step0found_at
  5. checks ← 1

    13do i = 1, size(values)14    checks = checks + 115    if (values(i) == target) then
    values this step0 1checks1i
  6. matched ← .false.

    14checks = checks + 115if (values(i) == target) then16    found_at = i
    values this step.false.matched3values(i)14target
  7. checks ← 2

    13do i = 1, size(values)14    checks = checks + 115    if (values(i) == target) then
    values this step1 2checks2i
  8. matched ← .false.

    14checks = checks + 115if (values(i) == target) then16    found_at = i
    values this step.false.matched6values(i)14target
  9. checks ← 3

    13do i = 1, size(values)14    checks = checks + 115    if (values(i) == target) then
    values this step2 3checks3i
  10. matched ← .false.

    14checks = checks + 115if (values(i) == target) then16    found_at = i
    values this step.false.matched9values(i)14target
  11. checks ← 4

    13do i = 1, size(values)14    checks = checks + 115    if (values(i) == target) then
    values this step3 4checks4i
  12. matched ← .false.

    14checks = checks + 115if (values(i) == target) then16    found_at = i
    values this step.false.matched12values(i)14target
  13. checks ← 5

    13do i = 1, size(values)14    checks = checks + 115    if (values(i) == target) then
    values this step4 5checks5i
  14. matched ← .false.

    14checks = checks + 115if (values(i) == target) then16    found_at = i
    values this step.false.matched15values(i)14target
  15. print '(I0, 1X, I0)', found_at, checks

    19    end do20    print '(I0, 1X, I0)', found_at, checks21end program early_exit_scan_demo
    output0 5
    values this step0found_at5checks
early exit `exit` leaves the loop as soon as the target is found.
checks `checks` shows the amount of scanning work performed.
sentinel `found_at = 0` records the not-found case without raising an error.