Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Performance of SELECT CASE

murpup1
Beginner
1,508 Views
I have recently been testing the performance of SELECT CASE. Specifically, how it performs when I use integer variables as the branching expression vs. strings. I am noticing some odd performance.

I have a DO loop that loops over a simple SELECT CASE statment, like this

INTEGER :: i
CHARACTER(len=8) :: string_var
string_var = 'someText'
DO i = 1, 100000000
SELECT CASE (string_var)
CASE ('string1')
a = 1
CASE ('string2')
a = 1
.
.
.
CASE ('someText')
a = 1
CASE DEFAULT
a = 1
END SELECT
END DO

When I execute this using a Release-compiled version, performance is relatively fast (0.44 sec). A similar SELECT CASE using integers instead of strings is even faster. But here is the weird part. If I replace the "a=1" statement in CASE DEFAULT
with

print *, 'no equivalent string'

run time slows to 3.25 secs, even though the print statement is never actually executed. If I add the print statement to the SELECT CASE using integers, I do not see this performance hit.

Why does this happen? Or am I doing something wrong?

Thanks in advance,
Chris
0 Kudos
4 Replies
Steven_L_Intel1
Employee
1,508 Views
I think you will find that the compiler decided to optimize the entire SELECT CASE (or even DO loop) away, since it could fold the whole thing into an a=1 statement.

Adding the PRINT meant that it couldn't do that.

In other words, you aren't measuring what you think you are measuring.

Steve
0 Kudos
murpup1
Beginner
1,508 Views
That certainly seems like it would explain it, although my spidey sense is still tingling.

Before playing around with the print statement, I tested the following 3 SELECT CASE configurations

integer_var = 10
SELECT CASE (integer_var)
CASE (1)
a=1
.
.
.
CASE (10)
a=1
CASE DEFAULT
a=1
END SELECT


char_var = 'someText'
SELECT CASE (char_var)
CASE ('string1')
a=1
.
.
.
CASE ('someText')
a=1
CASE DEFAULT
a=1
END SELECT

char_var2 = 'someText '
SELECT CASE (TRIM(char_var2))
CASE ('string1')
a=1
.
.
.
CASE ('someText')
a=1
CASE DEFAULT
a=1
END SELECT


Results were (over 100,000,000 iterations)

config 1 - 0.00 cpu secs (below resolution of my timer)
config 2 - 0.44 cpu secs
config 3 - 7.39 cpu secs

If the compiler was recognizing that "a=1" in all cases, and optimizing the SELECT CASE away, shouldn't I have seen the same performance in all 3 cases?

At any rate, having differing statements in each CASE is a better approach for this sort of benchmarking since it is closer to what would happen in the real world.

Thanks,
Chris
0 Kudos
Steven_L_Intel1
Employee
1,508 Views
I'd guess that in the third case, the compiler didn't realize that the result of the TRIM could be discarded. Even if you use different statements, if you never use A after the CASE, the compiler can still throw it all away.

Which compiler are you using?

Steve
0 Kudos
murpup1
Beginner
1,508 Views
CVF 6.6B

Thanks for your help, Steve

Chris
0 Kudos
Reply