I know that computer science generally frowns on GOTO statements, but is there a speed advantage to be gained by using
INTEGER WHICH
GOTO(100,200,300) WHICH
100 do something
GOTO 400
200 do something else
GOTO 400
300 do a third thing
GOTO 400
400 CONTINUE
versus
INTEGER WHICH
IF(WHICH.EQ.1)THEN
do something
ELSEIF(WHICH.EQ.2)THEN
do something else
ELSEIF(WHICH.EQ.3)THEN
do a third thing
ENDIF
since Fortran lacks a SWITCH statement?
First of all, as a general comment, these type of micro-optimizations are not really worth your time. More important is the answer to the question: What is easier to debug, understand and migrate?
Obligatory post: GOTO still considered harmful?
Having that said, I, unfortunately, have to inform you that the OP has a bug in his code-examples (here comes the raptor). The computed GOTO statement which you use has the following properties:
Execution of a computed GOTO statement causes evaluation of the scalar integer expression. If this value is i such that 1 ≤ i ≤ n where n is the number of labels in label-list, a branch occurs to the branch target statement identified by the ith label in the list of labels. If i is less than 1 or greater than n, the execution sequence continues as though a CONTINUE statement were executed.
source: Fortran 2008 Standard
This implies that the correct version should read:
INTEGER WHICH
GOTO(100,200,300) WHICH
GOTO 400 << missing part
100 do something
GOTO 400
200 do something else
GOTO 400
300 do a third thing
GOTO 400
400 CONTINUE
When you generate the assembly code of the following 3 files (see below), you will actually notice that the assembly code is identical under optimization. You can quickly check this yourself with the following lines in a bash script:
$ for i in f{1,2,3}.f90; do ifort -O3 -S $i; done
$ meld f{1,2,3}.s
You will also notice that, if you remove the goto 400
which was missing, the goto assembly code will be faster by a few instructions.
source of f1.f90:
subroutine g(a)
integer a
goto(100,200,300) a
goto 400
100 call f1()
goto 400
200 call f2()
goto 400
300 call f3()
goto 400
400 continue
end subroutine g
source of f2.f90:
subroutine g(a)
integer a
if(a.eq.1)then
call f1()
elseif(a.eq.2)then
call f2()
elseif(a.eq.3)then
call f3()
endif
end subroutine g
source of f3.f90:
subroutine g(a)
integer a
select case (a)
case (1)
call f1()
case (2)
call f2()
case (3)
call f3()
end select
end subroutine g