- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Adding the PRINT meant that it couldn't do that.
In other words, you aren't measuring what you think you are measuring.
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Which compiler are you using?
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
CVF 6.6B
Thanks for your help, Steve
Chris
Thanks for your help, Steve
Chris

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page