473,586 Members | 2,652 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Performance of switch{} block.

Just wondering if the sequence of the case(s) in the switch block might
impact performance. Suppose I switch on an int, and I have 4 expected cases.
Lets say I expect case 3 to happen 95% of the time. Would the switch block
be expected to execute faster (meaning "start executing the code for case 3
sooner") when case 3 appears first, as opposed to appearing as the 3rd
case:, as in the following code?

switch (someInt)
{
case 3:
// Do stuff here
break;
case 1:
// Do stuff here
break;
case 2:
// Do stuff here
break;
case 4:
// Do stuff here
break;
default:
// Do stuff here
break;
}

Just curious - and thought someone might already know offhand.

Thanks!
Dec 14 '06 #1
11 2513
Smithers wrote:
Just wondering if the sequence of the case(s) in the switch block might
impact performance. Suppose I switch on an int, and I have 4 expected cases.
Lets say I expect case 3 to happen 95% of the time. Would the switch block
be expected to execute faster (meaning "start executing the code for case 3
sooner") when case 3 appears first, as opposed to appearing as the 3rd
case:, as in the following code?

switch (someInt)
{
case 3:
// Do stuff here
break;
case 1:
// Do stuff here
break;
case 2:
// Do stuff here
break;
case 4:
// Do stuff here
break;
default:
// Do stuff here
break;
}
In principle, the compiler can build an array of code offsets (a
"vector table") and simply use the switch variable to index into. I am
under the impression that the C# compiler will do this, when the case
tags are all contiguous.

In practice, every switch statement I've ever unassembled is compiled
to an if-then-else-if tree. I do not know if this is a function of
debug mode, or whether the compiler will only use a vector table when
there are the "right" number of case statements.

In other words, yes, your case ordering probably does matter. Of
course, it would be a good idea to benchmark this (in Release mode,
without the debugger involved) to see if it makes any significant
difference. I'd be surprised if this was a big deal, outside of a loop
that's repeated millions of times a second.

--

..NET 2.0 for Delphi Programmers
www.midnightbeach.com/.net
What you need to know.
Dec 14 '06 #2
"Mark R. Dawson" <Ma*********@di scussions.micro soft.comwrote in message
news:B9******** *************** ***********@mic rosoft.com...
Hi Smithers,
the case statements are evaluated sequentially in the order they are
defined [...]
Is this really true?

I don't know how the C# compiler/run-time handles things, but a good C
compiler will often convert a switch() statement into a jump-table based
solution. If the cases are contiguous integers, a simple table can be
created with jump offsets to the correct place in code. With that solution,
handling the condition of the switch occurs in linear time, with each case
take equal amounts of time (not counting secondary issues like cache or
pipeline flushes, of course).

If C# does something like that, then the order of each case is irrelevant.
Each possible value takes the exact same time to process.

Of course, if C# naively just turns a switch() statement into a sequence of
if()/else if()... statements, then yes...the first one is the quickest. But
I haven't seen any documentation that suggests this is always what C# does
with a switch().

Pete
Dec 14 '06 #3
Look at the generated IL with ILDASM, and you'll get your answer right away.
Hint: code several switch statements with varying numbers of cases; a good
compiler, as you say, might use different techniques depending on how many
cases there are.

Tom Dacon
Dacon Software Consulting

"Peter Duniho" <Np*********@Nn OwSlPiAnMk.comw rote in message
news:12******** *****@corp.supe rnews.com...
"Mark R. Dawson" <Ma*********@di scussions.micro soft.comwrote in message
news:B9******** *************** ***********@mic rosoft.com...
>Hi Smithers,
the case statements are evaluated sequentially in the order they are
defined [...]

Is this really true?

I don't know how the C# compiler/run-time handles things, but a good C
compiler will often convert a switch() statement into a jump-table based
solution. If the cases are contiguous integers, a simple table can be
created with jump offsets to the correct place in code. With that
solution, handling the condition of the switch occurs in linear time, with
each case take equal amounts of time (not counting secondary issues like
cache or pipeline flushes, of course).

If C# does something like that, then the order of each case is irrelevant.
Each possible value takes the exact same time to process.

Of course, if C# naively just turns a switch() statement into a sequence
of if()/else if()... statements, then yes...the first one is the quickest.
But I haven't seen any documentation that suggests this is always what C#
does with a switch().

Pete

Dec 14 '06 #4
Hi

1. If you are very much sure about 95% of time case 3 (int =3) excutes,
it is quite reasonable to put it as a first case. (atleast for the sake
of readability and maintenace).

2. As I know switch statement is nothing but a if-else if - else if
...... else ladder. In which case placeing case 3 (int =3) as first case
makes sense.

3. Even if both of above statements ae wrong..... there is no harm to
your application ... I suppose.
Thanks
-Srinivas.

Smithers wrote:
Just wondering if the sequence of the case(s) in the switch block might
impact performance. Suppose I switch on an int, and I have 4 expected cases.
Lets say I expect case 3 to happen 95% of the time. Would the switch block
be expected to execute faster (meaning "start executing the code for case 3
sooner") when case 3 appears first, as opposed to appearing as the 3rd
case:, as in the following code?

switch (someInt)
{
case 3:
// Do stuff here
break;
case 1:
// Do stuff here
break;
case 2:
// Do stuff here
break;
case 4:
// Do stuff here
break;
default:
// Do stuff here
break;
}

Just curious - and thought someone might already know offhand.

Thanks!
Dec 14 '06 #5
"Smithers" <A@B.comwrote :
>Just wondering if the sequence of the case(s) in the switch block might
impact performance.
Question: will the JIT ever optimize the switch statement at runtime,
based on the behaviour it has been observing so far during execution
of the program?

--
Lucian
Dec 14 '06 #6
Lucian Wischik <lu***@wischik. comwrote:
"Smithers" <A@B.comwrote :
Just wondering if the sequence of the case(s) in the switch block might
impact performance.

Question: will the JIT ever optimize the switch statement at runtime,
based on the behaviour it has been observing so far during execution
of the program?
The .NET JIT is a "one time" JIT - it doesn't recompile code after it's
done it once. (This is in contrast to Hotspot, Sun's Java JIT, which
recompiles based on changes to optimisation strategies etc.)

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 14 '06 #7
Jon Shemitz <jo*@midnightbe ach.comwrote:

<snip>
In practice, every switch statement I've ever unassembled is compiled
to an if-then-else-if tree. I do not know if this is a function of
debug mode, or whether the compiler will only use a vector table when
there are the "right" number of case statements.
I suspect it will happen if you've got "sparse" case statements. In
this case, however, it looks to me like it's using a table (as one
would hope, to be honest).

Here's a C# program:

using System;

class Test
{
static void Main()
{
int someInt = 3;

switch (someInt)
{
case 3:
Console.WriteLi ne ("3");
// Do stuff here
break;
case 1:
Console.WriteLi ne ("1");
// Do stuff here
break;
case 2:
Console.WriteLi ne ("2");
// Do stuff here
break;
case 4:
Console.WriteLi ne ("4");
// Do stuff here
break;
default:
// Do stuff here
break;
}
}
}

and here's the disassembled code in cordbg with JitOptimization s turned
on:

[0000] push edi
[0001] push esi
[0002] cmp dword ptr ds:[001C2DECh],0
[0009] je 00000007
[000b] call 792DD123
[0010] xor esi,esi
[0012] xor edi,edi
[0014] mov esi,3
[0019] mov edi,esi
[001b] lea eax,[edi-1]
[001e] cmp eax,4
[0021] jae 00000009
[0023] jmp dword ptr [eax*4+00DB9C18h]
[002a] nop
[002b] jmp 0000003E
[002d] mov ecx,dword ptr ds:[02412098h]
[0033] call dword ptr ds:[00DF0ECCh]
[0039] nop
[003a] jmp 0000002F
[003c] mov ecx,dword ptr ds:[0241209Ch]
[0042] call dword ptr ds:[00DF0ECCh]
[0048] nop
[0049] jmp 00000020
[004b] mov ecx,dword ptr ds:[024120A0h]
[0051] call dword ptr ds:[00DF0ECCh]
[0057] nop
[0058] jmp 00000011
[005a] mov ecx,dword ptr ds:[024120A4h]
[0060] call dword ptr ds:[00DF0ECCh]
[0066] nop
[0067] jmp 00000002
[0069] pop esi
[006a] pop edi
[006b] ret

I'm not an expert in x86, but this looks to me like a straight jump
rather than a series of comparisons.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 14 '06 #8
"Smithers" <A@B.comwrote in message news:ez******** *****@TK2MSFTNG P02.phx.gbl...
Just wondering if the sequence of the case(s) in the switch block might impact
performance. Suppose I switch on an int, and I have 4 expected cases. Lets say I expect
case 3 to happen 95% of the time. Would the switch block be expected to execute faster
(meaning "start executing the code for case 3 sooner") when case 3 appears first, as
opposed to appearing as the 3rd case:, as in the following code?

switch (someInt)
{
case 3:
// Do stuff here
break;
case 1:
// Do stuff here
break;
case 2:
// Do stuff here
break;
case 4:
// Do stuff here
break;
default:
// Do stuff here
break;
}

Just curious - and thought someone might already know offhand.

Thanks!


No, it doesn't matter where you put case, the JIT builds a jump table and uses the switch
"value" as an index into that table and uses the contents of (index*4 + table_start_add ress)
as the address to jump to.

The jump table For your switch block on X86, would look something like this:
003601b8 00360105 < - index 0
00360133 <- index 1
003600d2 <- index 2
00360162 <- index 3

and the jump instruction like this:
jmp dword ptr [eax*4+3601B8h]

the index in eax is the calculated value of the switch expression-1, so for the case 1 the
jmp will be made to 00360105 , for case 2 a jump is made to 00360133 etc...
Willy.
..

Dec 14 '06 #9
"Jon Skeet [C# MVP]" <sk***@pobox.co mwrote in message
news:MP******** *************** *@msnews.micros oft.com...
Jon Shemitz <jo*@midnightbe ach.comwrote:

<snip>
>In practice, every switch statement I've ever unassembled is compiled
to an if-then-else-if tree. I do not know if this is a function of
debug mode, or whether the compiler will only use a vector table when
there are the "right" number of case statements.

I suspect it will happen if you've got "sparse" case statements. In
this case, however, it looks to me like it's using a table (as one
would hope, to be honest).

Here's a C# program:

using System;

class Test
{
static void Main()
{
int someInt = 3;

switch (someInt)
{
case 3:
Console.WriteLi ne ("3");
// Do stuff here
break;
case 1:
Console.WriteLi ne ("1");
// Do stuff here
break;
case 2:
Console.WriteLi ne ("2");
// Do stuff here
break;
case 4:
Console.WriteLi ne ("4");
// Do stuff here
break;
default:
// Do stuff here
break;
}
}
}

and here's the disassembled code in cordbg with JitOptimization s turned
on:

[0000] push edi
[0001] push esi
[0002] cmp dword ptr ds:[001C2DECh],0
[0009] je 00000007
[000b] call 792DD123
[0010] xor esi,esi
[0012] xor edi,edi
[0014] mov esi,3
[0019] mov edi,esi
[001b] lea eax,[edi-1]
[001e] cmp eax,4
[0021] jae 00000009
[0023] jmp dword ptr [eax*4+00DB9C18h]
[002a] nop
[002b] jmp 0000003E
[002d] mov ecx,dword ptr ds:[02412098h]
[0033] call dword ptr ds:[00DF0ECCh]
[0039] nop
[003a] jmp 0000002F
[003c] mov ecx,dword ptr ds:[0241209Ch]
[0042] call dword ptr ds:[00DF0ECCh]
[0048] nop
[0049] jmp 00000020
[004b] mov ecx,dword ptr ds:[024120A0h]
[0051] call dword ptr ds:[00DF0ECCh]
[0057] nop
[0058] jmp 00000011
[005a] mov ecx,dword ptr ds:[024120A4h]
[0060] call dword ptr ds:[00DF0ECCh]
[0066] nop
[0067] jmp 00000002
[0069] pop esi
[006a] pop edi
[006b] ret

I'm not an expert in x86, but this looks to me like a straight jump
rather than a series of comparisons.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too


Yep, the important part is this:

[001b] lea eax,[edi-1]
[001e] cmp eax,4
[0021] jae 00000009
[0023] jmp dword ptr [eax*4+00DB9C18h]
[002a] nop

here the *index*, that is the number of 'cases'is caluclated and compared against the
maximum valid value, 4 in this sample.
If the value is larger a jump s made to current IP + 000000009 (to [002a] nop) else, a
jump is made to the address in the jump table at address eax*4., where eax = index and
00DB9C18h is the start of the table. Note that on 64 bit the index is obviously multiplied
by 8.

Note the [002a] nop, this means that the code is not JIT optimized!!

Willy.

Dec 14 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

133
8491
by: Gaurav | last post by:
http://www.sys-con.com/story/print.cfm?storyid=45250 Any comments? Thanks Gaurav
6
2191
by: Jason Heyes | last post by:
I am starting to worry about the performance of formatted read/write operations on data-redundant objects in my program.What can I do to improve this performance should it become an issue? Thanks.
18
3438
by: Minti | last post by:
I was reading some text and I came across the following snippet switch('5') { int x = 123; case '5': printf("The value of x %d\n", x); break; }
6
2821
by: RepStat | last post by:
I've read that it is best not to use exceptions willy-nilly for stupid purposes as they can be a major performance hit if they are thrown. But is it a performance hit to use a try..catch..finally block, just in case there might be an exception? i.e. is it ok performance-wise to pepper pieces of code with try..catch..finally blocks that must be...
15
3503
by: Benny Raymond | last post by:
I'm confused as to how fallthrough is limited in switch. For example the following works: string switch_test = "a"; switch (switch_test) { case "a": case "b": case "c": doSomething(a);
46
13088
by: dunleav1 | last post by:
I have a process that does inserts that runs 50% slower that Oracle and Mssql. Queries normally take 50% slower than normal. DB2, Oracle, Mssql all are configured on same os, same disk array (raid 1/0 - 15k disks) but DB2 I/O seems to be significantly slower. Tablespaces are SMS with automatic prefetch set. My thought was to create the...
13
4586
by: atlaste | last post by:
Hi, I'm currently developing an application that uses a lot of computational power, disk access and memory caching (to be more exact: an information retrieval platform). In these kind of applications the last thing that remains is bare performance tuning. So for example, you can do an 'if then else' on a bit like a 'case/ switch', an...
0
1112
by: Ketchup | last post by:
Hello everyone, I am writing a utility. Part of its function is to do a block-mode copy of files and generate MD5 / SHA1 hashes on the fly. The functionality is similar to that of the Unix DD / DCFLDD utilities. I am using API calls to get handles to files and FileStreams to perform the copy block by block, hashing on the way. The...
13
6583
by: rdudejr | last post by:
Hi all, I hardly ever make a post unless I am having a very purplexing issue, so this one should be good... I am trying to do a load against a database on an AIX server into a DB2 v9.1 database, using SAN for storage. The table has a few CLOBs (smallish clobs but we are storing XML data in non-native format). Here is the load command I...
0
7912
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
8338
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7959
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
8216
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6614
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5710
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5390
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
1
2345
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
0
1180
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.