I have numerous if statements that read something like
if ((foo == 1).or.(foo == 2).or.(foo == 3).or.(foo == 4)) then
call bar1
end if
if ((foo == 3).or.(foo == 4).or.(foo == 5).or.(foo == 6)) then
call bar2
end if
Are there any reasons (w.r.t. speed, style, etc.) to not use something like this?
if (any(foo == (/1,2,3,4/))) call bar1
if (any(foo == (/3,4,5,6/))) call bar2
Addition: In my real example the numbers are not necessarily sequentially. So I can not use
if ((foo >= 1).and.(foo <=4)) call bar1
if ((foo >= 3).and.(foo <=6)) call bar1
Addition2: the overlap of the two if conditions is deliberate, which makes it in my understanding impossible to use the SELECT CASE statement
CodePudding user response:
Converting my comment to an answer so the question can be ticked off ...
With regards to the speed part of the question - if this is a concern for you then test and measure. If you don't think it's worth your time testing and measuring then (a) you're probably right, I don't think that I have ever worked on a significant Fortran program where the speed differences between the two approaches could have been of material interest; and (b) it's not worth my time either!
As to the style - that part of the question is off-topic here - but I don't find it all objectionable, though I might write a wee function with signature memberQ(foo, list)
and the obvious implementation.
CodePudding user response:
High Performance Mark has answered most of your question, but allow me to present a nice alternative method.
Fortran allows operator overloading, and this allows us to overload .in.
to see if an item is in a list. The code for this would look like
module in_module
implicit none
interface operator(.in.)
module procedure integer_in_integer_list
end interface
contains
function integer_in_integer_list(item, list) result(output)
integer, intent(in) :: item
integer, intent(in) :: list(:)
logical :: output
output = any(item==list)
end function
end module
And then your code simply becomes
if (foo .in. [1,2,3,4]) call bar1
if (foo .in. [3,4,5,6]) call bar2
In my opinion this is the cleanest way of doing this, and it should have similar performance to other methods. You can overload .in.
to take other types (including user-defined types) as needed.