This may be a stupid question, but I'm interested in the performance of using try/catch blocks.
I have a DataGrid that assigns a Converter to the background property of a DataGridCell. In the converter, I compare the value of this year's data to last year's data; if this year's data is > 3%, I return a Green background; if it's > 0% and < 3%, I return a Yellow; and if it's < 0%, I return Red:
string x = values[0].ToString().Replace("$", "").Replace(",", ""); //This year's number
string y = values[1].ToString().Replace("$", "").Replace(",", ""); //Last year's
result = (((float.Parse(x) * 100) / float.Parse(y)) - 1) * 100;
if (result >= 3)
return Brushes.LimeGreen;
else if (result >= 0)
return Brushes.Yellow;
else
return Brushes.Red;
However, in some cases, the cell will NOT have a value of last year; as you can guess, dividing by 0 (or some text as the Converter seems to receive when the Cell is empty) is a pretty bad idea and will throw an exception. So, I decided the easiest way to deal with this was:
try
{
result = (((float.Parse(x) * 100) / float.Parse(y)) - 1) * 100;
}
catch
{
return Brushes.DarkOrange;
}
So if the exception is thrown (whereby there is no value to compare to), return an Orange and call it a day. (edit: yes, I do wish to return an Orange when there is no value to compare to.
Currently, I can predict that it will only happen to one row of data for now, so it only catches about 10 cells when it's populated. But as the future goes on, it has the possibility of having it happen more times.
The try/catch block is the easiest and quickest way to handle this(as far as I can tell), but it is obviously not the only way, especially since I know the error. So Is using a try/catch block a bad idea in this case? And by bad idea, I mean will it slow performance since it is iterated over many, many times? Given that I know what the error will be, should I preempt it, or is using a try/catch block fine?
This is a bad idea. It's not an exceptional situation, so don't handle it like it's one. The fact that you're worried about performance and exception handling is a smell that you're doing something wrong. There is a really simple way to handle this, so I don't even see why you ever thought to instead handle it using exception handling.
Yes, it will impact your performance but that shouldn't be your concern here. Your concern should be what is the clearest way to write this logic, and using exceptions is clearly not the way.
Here's that simple way:
double value;
if(!Float.TryParse(y, out value) || value == 0f) {
return Brushes.DarkOrange;
}
else {
double result = (((float.Parse(x) * 100) / value) - 1) * 100;
if (result >= 3) {
return Brushes.LimeGreen;
}
else if (result >= 0) {
return Brushes.Yellow;
}
else {
return Brushes.Red;
}
}
In general, exceptions should be used for truly exceptional cases - cases which are not expected. In a situation like this, where you're well aware that there could be no prior year, I'd suggest using simple if() checks to return your default values.
To answer your performance question, Microsoft says that "Throwing exceptions can negatively impact performance".
The try catch has one of the worst performances on the .Net framework. Look here When an exception is raised the stacktrace has to be checked to find in which method there is a catch for that specific exception and this is a costly operation.
Never do things like that with exceptions if you have performance in mind (and I would say even if you don't have performance on mind).
Catch statements should only be used for catching Exceptions..Not altering the program flow, So to answer your question, yes this is a bad idea.
And I can't imagine it to be performant, because a new Exception object will be created and most likely java will do some logging of the event, so your better of just using an if statement.
Using the catch block in the way you described in your question is a bad idea. Try-catch blocks themselves do not have a huge performance impact, but exceptions do have a large performance cost.
The best option is to use the TryParse method on the float class instead. There is a reason it exists.
I believe Rico Mariani has the last word, as usual:
The True Cost of .NET Exceptions
Yes, using a Try/Catch block is a very bad idea.
I am not familiar enough with the intricacies of c# to tell you whether an if, or a tryparse statement or a try catch are going to be faster. What I can offer you is the idea of thinking about calls.
If you're worried about performance on something as simple as implementation of the same process, think about the number of calls as well. If you check every single number if it's 0, or call try-parse on every single number then you're adding that call to every iteration, not just the iterations that fail. If this implementation works for you, it is a good approach as it only gets into the catch block when it fails.
For many programs, this sort of implementation wouldn't work, because they want to do additional processing in the catch block. For those programs, you'd want to check for the 0, or do the tryparse. Since you're just returning, I believe this makes for easily readable code.
Related
My knowledge with try catch is limited. But i wonder if it can be used to gain performance.
Example, i am creating this voxel engine where a function is like this:
Block GetBlockInChunk(Vector Position){
if(InBound(Position)){
return Database.GetBlock();
}
return null;
}
Here it has to check bounds of the given position, with using try catch, then you can remove them?
Block GetBlockInChunk(Vector Position){
try{
return Database.GetBlock();
}
catch{
return null;
}
}
I feel like this is probably terrible practice, but i am curious.
The link I provided in the above comment shows a description of why you shouldn't ever use a try-catch when an if-statement would prevent the exception from being thrown, but in the interest of showing performance in terms of actual numbers, I wrote this quick little test program.
Stopwatch watch = new Stopwatch();
int[] testArray = new int[] { 1, 2, 3, 4, 5 };
int? test = null;
watch.Start();
for (int i = 0; i < 10000; i++)
{
try
{
testArray[(int)test] = 0;
}
catch { }
}
watch.Stop();
Console.WriteLine("try-catch result:");
Console.WriteLine(watch.Elapsed);
Console.WriteLine();
watch.Restart();
for (int i = 0; i < 10000; i++)
{
if (test != null)
testArray[(int)test] = 0;
}
watch.Stop();
Console.WriteLine("if-statement result:");
Console.WriteLine(watch.Elapsed);
The result of the program is this:
try-catch result:
00:00:32.6764911
if-statement result:
00:00:00.0001047
As you can see, the try-catch approach introduces significant overhead when an exception gets caught, taking over 30 seconds to complete 10,000 cycles on my machine. The if-statement, on the other hand, runs so fast that it is basically instantaneous. Compared to the try-catch, this is a performance improvement in the neighborhood of 3,000,000%.
(This isn't a rigorous benchmark, and there are ways to write it and run it differently to get more precise numbers, but this should give you a good idea of just how much more efficient it is to use an if-statement over a try-catch whenever possible.)
It is about 2 years later, but it is still relevant...
I respect the other replies but I believe there is a basic misunderstanding here for the purpose of try-catch. Try Catch is a very effective way within the C# and dotnet, to identify errors over the development and the life of the code. It is never intended to be a tool to use different, and if it is been fire, it means that you have a bug that needs to be fixed.
The problem it comes to solve is the standard error message that stops the code and then you need to dig in. With try and catch you can know in which method the problem occurs and narrow down the search.
As standard, I wrap ALL my methods with try-catch and added an additional functionality that writes the error message with the name of the method and additional essential information like time, and some helpful anchors of data to a debug file, which I can access even when the code is in production. This is priceless!
As far as performance, if the try-catch doesn't fire (which should be normal), there is no performance reduction, as it is merely a simple warper. If someone is really into a high level of performance and every fraction matter, it is possible to eliminate it using precompiler conditions (#if...).
Hope this is helpful.
I am fairly new to c# and trying to learn best practices. I've been faced with many situations over the last week in which I need to make a choice between longer+simpler code, or shorter code that combines several actions into a single statement. What are some standards you veteran coders use when trying to write clear, concise code? Here is an example of code I'm writing with two options. Which is preferable?
A)
if (ncPointType.StartsWith("A"))//analog points
{
string[] precisionString = Regex.Split(unitsParam.Last(), ", ");
precision = int.Parse(precisionString[1]);
}
else
precision = null;
B)
if (ncPointType.StartsWith("A"))//analog points
precision = int.Parse(Regex.Split(unitsParam.Last(), ", ")[1]);
else
precision = null;
There is no right or wrong. This is opinion based really.
However, remember that whether you add braces, add comments, add whitespace or whatever, it doesn't affect the performance or the size of the final assembly because the compiler optimizes it very well. So, why not go with the more verbose so that other programmers can follow it easier?
This is basically subject to the coding standard you choose. There is no right or wrong, just personal preference.
Agree as a team what you prefer.
But even better is:
precision = ncPointType.StartsWith("A")?
int.Parse(Regex.Split(unitsParam.Last(), ", ")):
null;
This expresses the function beiong executed (set the precision),
and the conditions that control how it is set, in even less code,
- without creating unnecessary temporary variables to hold a temporary result that is not used anywhere else.
If you ask me both A and B are bad practice. You should always use braces regardless of whether or not it is one line or multiple lines. This helps to prevent bugs in the future when people add additional lines of code to your if or else blocks and don't notice that the braces are missing.
Sometimes having "more" code, like using temporary variables, etc., will make your code easier to debug as you can hover over symbols. It's all about balance, and this comes with experience. Remember that you may not be the only one working on your code, so clarity above all.
Ultimately it comes down to your choice because it has nothing to do with performance, but I would also note that you cannot instantiate or define variables if you omit the curly braces:
int a = 0;
if (a == 0)
int b = 3;
Is not valid, whereas:
int a = 0;
if (a == 0)
{
int b = 3;
}
Is valid.
It's easier to debug option A, but option B is more concise while still being readable. You could make it even more concise with a ternary operator:
precision = ncPointType.StartsWith("A") ? int.Parse(Regex.Split(unitsParam.Last(), ", ")[1]) : null;
Although it's far more readable this way (and still works the same way!):
precision = ncPointType.StartsWith("A") ?
int.Parse(Regex.Split(unitsParam.Last(), ", ")[1]) :
null;
It's best to stick with the standards used in your project. Readability is far more important for maintainability than having less lines of code. In both options, the efficiency is the same, so you don't need to worry about speed in this case.
As everyone else here points out, there are no hard and fast "rules" per se, but there should probably be braces around both block of code; both A and B have characteristics similar to the Apple goto bug because the introduce potential ambiguity.
Consider:
void Main()
{
int x=1;
if (x==1)
Console.WriteLine("1");
else if (x==2)
Console.WriteLine("NOT 1");
Console.WriteLine("OK");
}
will produce
1
OK
To someone scanning the code, especially if it's surrounded by other, innocuous looking code, this could easily be misread as "only print "OK" if x==2). Obviously some people will spot it, some won't, but why introduce the danger for the want of a brace of braces :)
1) I know how if…else if statements work, but in the next example both methods are identical as far as the resulting value is concerned. So does it matter which of the two methods I use or should I always go for one that is semantically closest to what the code is trying to do ( here I’m guessing that semantically the two methods are quite different )? So which method would you use and why?
protected string GetNumberDescription(int value)
{
if (value >= veryBigNumber)
return veryBigNumberDescription;
else if (value >= bigNumber)
return bigNumberDescription;
else if (value >= smallNumber)
return smallNumberDescription;
else
return "";
}
protected string GetNumberDescription(int value)
{
if (value >= veryBigNumber)
return veryBigNumberDescription;
if (value >= bigNumber)
return bigNumberDescription;
if (value >= smallNumber)
return smallNumberDescription;
else
return "";
}
2) I noticed losts of code uses the following format when writting if ... else if statements:
if ...
else if ...
else ...
But isn't ( at least conceptually ) more correct way:
if ...
else
if ...
else ...
You should probably use the first. It's more accepted, and more logical. (You don't care about anything afterwards if this condition is true... indicate that in your code.)
It's generally more accepted, and more compact and readable, to use the first way (else if). Python even has a specific keyword for it (elif).
I personally would use
protected string GetNumberDescription(int value)
{
if (value >= veryBigNumber)
return veryBigNumberDescription;
if (value >= bigNumber)
return bigNumberDescription;
if (value >= smallNumber)
return smallNumberDescription;
return string.Empty;
}
It really all depends on what your function is doing. If its simple like this then keep it simple. If you might need to do something with the result before you return it then I'd use Egrunin's solution
protected string GetNumberDescription(int value)
{
string ret = "";
if (value >= veryBigNumber)
ret = veryBigNumberDescription;
else if (value >= bigNumber)
ret = bigNumberDescription;
else if (value >= smallNumber)
ret = smallNumberDescription;
return ret;
}
The question is already answered, but I added this because:
There are advantages to having a single exit from a function.
The same variable is being tested repeatedly, so the if/elseif is most appropriate.
Edited to add:
I'm usually a big fan of exiting a function early in cases like this:
if (conditionOne)
{
if (conditionTwo)
{
if (conditionThree)
{
interesting_stuff();
}
}
else
boring();
}
return;
I'm much happier seeing this:
if (!conditionOne)
return;
if (!conditionTwo)
{
boring();
return;
}
if (!conditionThree)
return;
interesting_stuff();
return;
But when there are exits at many different nesting levels, it's too easy to miss one as you're reading over the code.
Also, as mentioned in the comments: a single exit means only one place to put a breakpoint.
If the conditions are mutually exclusive then I think an else if pattern is best. It will be harder to accidentally break as the code evolves and becomes more complex, because your control flow more accurately represents the mutual exclusiveness of the logic.
Consider if someone re-factored your first example to be similar to egrunin's example such that there is only one return, but consider they forgot to add the "else" to each if:
protected string GetNumberDescription(int value)
{
string ret = "";
if (value >= veryBigNumber)
ret = veryBigNumberDescription;
if (value >= bigNumber)
ret = bigNumberDescription;
if (value >= smallNumber)
ret = smallNumberDescription;
// BUG: very big numbers still fall through to this last condition,
// because they meet all conditions
return ret;
}
They have just introduced a bug. They may not have realized that the returns were part of the logic being expressed. While the error is obvious here, in real life this code a couple years down the road could potentially become more complex, lengthy, and more difficult to read such that it's easier to make such a mistake.
Detecting Unexpected Bug
Additionally, if at least one condition must be met(i.e. should never return an empty string), then I'd throw an exception in the final else if you are assuming all cases should be handled. This would detect a bug in the code where the code fell through all the elses and did not find a matching condition. If you do not throw an exception, then the bug might cause strange behavior. How will the rest of the code handle the uninitialized empty string? Depends largely on the code at hand. The idea of throwing an exception is to cause a hard failure exactly where the bug is so that it can be easily identified and corrected, instead of allowing the application to continue running with an invalid return.
if (value >= smallNumber)
ret = smallNumberDescription;
else if(...)
ret = otherNumberDescription;
else
throw new InvalidOperationException($"No condition matched for value={value}");
return ret;
If paired with appropriate exception logging/notifications, then this would allow you to become aware of this bug and add a condition to handle unanticipated values. Not really necessary for very simple conditions, but very helpful in proactively finding and correcting bugs in this kind of code.
They are semantically identical. I doubt there is any difference in performance, so the choice is about style and readability. If you're curious, compile the above code into an assembly and use Reflector to see if there is any difference in the IL. My guess is there would be little difference if any.
It's mostly a matter of preference. when using return statements, you don't need the elses in my opinion, since it's clear that the function ends right there. It's all very situation and style dependent, so there is no clear 'best' way to do it.
I would suggest the former, as you are making a logical choice between four possibilities. You are grouping the decision in one if/else if block.
If you separate out the decisions like in your second function, they appear to not be connected at all. Clearly they are, as the value variable is repeated, but it might not necessarily be obvious.
Additionally, when you've got nothing to return, please return null, and not a blank string. In an application I maintain, it is still necessary to use if (value == null || value != "").
You want to use "else if" because that only will fire if the first "if" is not accepted. In your case the 3 if statements are okay, simply because if a latter "if" is correct, then the previous "if"s cannot be.
In a case where all of your if statements could be correct, you'd want to use else if.
For Example:
if (8<10) {
return 10;
}
if (8<9) {
return 9;
}
That's a very simplistic example, but you get the idea. You use "else if" when you want only one "if" statement to fire.
I would use the first option, as it shows in code the comparisons are "grouped" some. For 2 I think they end up in exactly the same IL code.
I always make sure the most common senario is first in the if..else statement, as that is best for performance.
The alternatives are pretty close semantically, so it doesn't matter that much. As suggested in some answers, putting the result in a string variable and return at the end might better represent what you are doing in the method.
Another alternative is to use the conditional operand, which gives you a less verbose code:
protected string GetNumberDescription(int value) {
return
value >= veryBigNumber ? veryBigNumberDescription :
value >= bigNumber ? bigNumberDescription :
value >= smallNumber ? smallNumberDescription :
String.Empty;
}
With the return statements, it really doesn't matter. I totally disagree with those who say the second is in any way worse, though. What makes it worse?
In response to your second question: you are quite right. In fact, not only are the two ways of formatting if/else if effectively the same; they actually are literally the same. C# does not enforce a particular formatting style, so these are all identical:
// This...
if (A())
return "Congrats!";
else if (B())
return "Not bad!";
else if (C())
return "Next time...";
else
return "Uh-oh.";
// ...is the same as this...
if (A())
return "Congrats!";
else
if (B())
return "Not bad!";
else
if (C())
return "Next time...";
else
return "Uh-oh.";
// ...which is the same as this...
if (A()) return "Congrats!"; else
if (B())
return "Not bad!";
else
{ if
(C())
return
"Next time...";else{
return "Oh-oh.";
}}
protected string GetNumberDescription(int value)
{
return new NumberDescriptor(value).toString();
}
All you need is to hide your logic.
Don't take this too serious, but...i would do it that way. I know, your question is not anserwed here, but there are already enough if/then/else examples in this topic.
1) The first one is more prevalent and in common practice. So it would be wise to stick to the standard practice.
2) Generally when we have more than one conditional statement, else if is used in the intermediate conditional outputs and else is used in the last conditional output. Moreover it might be more efficient as I believe it does not have to check the same condition everytime unlike the if-else-if-else... type.
Its more like a choice provided to you where you find your own out of many paths going to the same destination. But the choice that you hear or see often is the one that is popular because of experience of many users and experts.
I would say to use the first if the function is thought of as returning one of four possibilities, all of which are considered "successful". I would use the latter style if some returns denoted "failures". For example (toy example--throwing might be better for the error cases):
string get_suit_name(int suit)
{
string suit_names[4] = {"clubs", "diamonds", "hearts", "spades"};
if (0 > suit) /* Avoid LT sign */
return "Suit is improperly negative!";
if (suit >= 4)
return "Suit is too big!";
return suit_names[suit];
}
Well from my point of view it would be these priorities from highest to lowest.
Functionality / achieving the end goal
Reduction of cost in any scope/level
Readability
^^^^ note that many will dispute this on my list and call readability above reduction of cost, it really depends on your work envi. and the end goal but I find this the most common. But guess coming from a rookie that doesn't mean much huh :D
After that you it's pretty much peanuts. Same goes for ? : operator. If you are convinced it's more readable, go for it. Function wise it doesn't really matter. But if(){}else{} is significantly different from if(){}else if(){} So pick what's the optimum code (Highest wanted results minus unexpected results - 0.5* readability score ) pretty much what I'd go on.
Now seeing as the code does the same for you, a new attribute comes into play, will this code be edited at some later stage? And if so what would be best to go for then? Don't forget the future of the code, nor the comments, that a free bonus to pick along with it. You can even do both if you can't figure it out for the time and just comment the other but that does leave sloppy walls of text to be removed later on cleanup/release.
For the example provided, you don't need to worry about "if" statements if you're willing to sacrifice a ton of readability and possibly a little speed:
string [] descriptions = {"", smallNumberDescription, bigNumberDescription, veryBigNumberDescription};
protected string GetNumberDescription(int value)
{
int index = Convert.ToInt32(value >= smallNumber) + Convert.ToInt32(value >= bigNumber)
+ Convert.ToInt32(value >= veryBigNumber);
return descriptions[index];
}
In terms of performance, they may be the same depending on the compiler/interpreter. In my opinion the second one is better....much easier to debug.
Well, in your particular case, I would suggest this:
protected string GetNumberDescription(int value) {
if (value >= veryBigNumber)
return veryBigNumberDescription;
if (value >= bigNumber)
return bigNumberDescription;
if (value >= smallNumber)
return smallNumberDescription;
return "";
}
Since, you are returning from the function on any of the true condition, there is no need to use 'else if'. In your case, if any of the conditions become true, the code won't execute further.
Also, the last 'else' is not required, for the control will reach that point only when all the above conditions have been false.
It's all a matter of where you're using it, and how. The main motive is to maximize the readability of your code and make it as elegant and easy-to-understand as possible.
Many would prefer the first way since it indicates in your code that you don't care what happens as soon as a condition is satisfied.
Possible Duplicates:
While vs. Do While
When should I use do-while instead of while loops?
I've been programming for a while now (2 years work + 4.5 years degree + 1 year pre-college), and I've never used a do-while loop short of being forced to in the Introduction to Programming course. I have a growing feeling that I'm doing programming wrong if I never run into something so fundamental.
Could it be that I just haven't run into the correct circumstances?
What are some examples where it would be necessary to use a do-while instead of a while?
(My schooling was almost all in C/C++ and my work is in C#, so if there is another language where it absolutely makes sense because do-whiles work differently, then these questions don't really apply.)
To clarify...I know the difference between a while and a do-while. While checks the exit condition and then performs tasks. do-while performs tasks and then checks exit condition.
If you always want the loop to execute at least once. It's not common, but I do use it from time to time. One case where you might want to use it is trying to access a resource that could require a retry, e.g.
do
{
try to access resource...
put up message box with retry option
} while (user says retry);
do-while is better if the compiler isn't competent at optimization. do-while has only a single conditional jump, as opposed to for and while which have a conditional jump and an unconditional jump. For CPUs which are pipelined and don't do branch prediction, this can make a big difference in the performance of a tight loop.
Also, since most compilers are smart enough to perform this optimization, all loops found in decompiled code will usually be do-while (if the decompiler even bothers to reconstruct loops from backward local gotos at all).
I have used this in a TryDeleteDirectory function. It was something like this
do
{
try
{
DisableReadOnly(directory);
directory.Delete(true);
}
catch (Exception)
{
retryDeleteDirectoryCount++;
}
} while (Directory.Exists(fullPath) && retryDeleteDirectoryCount < 4);
Do while is useful for when you want to execute something at least once. As for a good example for using do while vs. while, lets say you want to make the following: A calculator.
You could approach this by using a loop and checking after each calculation if the person wants to exit the program. Now you can probably assume that once the program is opened the person wants to do this at least once so you could do the following:
do
{
//do calculator logic here
//prompt user for continue here
} while(cont==true);//cont is short for continue
This is sort of an indirect answer, but this question got me thinking about the logic behind it, and I thought this might be worth sharing.
As everyone else has said, you use a do ... while loop when you want to execute the body at least once. But under what circumstances would you want to do that?
Well, the most obvious class of situations I can think of would be when the initial ("unprimed") value of the check condition is the same as when you want to exit. This means that you need to execute the loop body once to prime the condition to a non-exiting value, and then perform the actual repetition based on that condition. What with programmers being so lazy, someone decided to wrap this up in a control structure.
So for example, reading characters from a serial port with a timeout might take the form (in Python):
response_buffer = []
char_read = port.read(1)
while char_read:
response_buffer.append(char_read)
char_read = port.read(1)
# When there's nothing to read after 1s, there is no more data
response = ''.join(response_buffer)
Note the duplication of code: char_read = port.read(1). If Python had a do ... while loop, I might have used:
do:
char_read = port.read(1)
response_buffer.append(char_read)
while char_read
The added benefit for languages that create a new scope for loops: char_read does not pollute the function namespace. But note also that there is a better way to do this, and that is by using Python's None value:
response_buffer = []
char_read = None
while char_read != '':
char_read = port.read(1)
response_buffer.append(char_read)
response = ''.join(response_buffer)
So here's the crux of my point: in languages with nullable types, the situation initial_value == exit_value arises far less frequently, and that may be why you do not encounter it. I'm not saying it never happens, because there are still times when a function will return None to signify a valid condition. But in my hurried and briefly-considered opinion, this would happen a lot more if the languages you used did not allow for a value that signifies: this variable has not been initialised yet.
This is not perfect reasoning: in reality, now that null-values are common, they simply form one more element of the set of valid values a variable can take. But practically, programmers have a way to distinguish between a variable being in sensible state, which may include the loop exit state, and it being in an uninitialised state.
I used them a fair bit when I was in school, but not so much since.
In theory they are useful when you want the loop body to execute once before the exit condition check. The problem is that for the few instances where I don't want the check first, typically I want the exit check in the middle of the loop body rather than at the very end. In that case, I prefer to use the well-known for (;;) with an if (condition) exit; somewhere in the body.
In fact, if I'm a bit shaky on the loop exit condition, sometimes I find it useful to start writing the loop as a for (;;) {} with an exit statement where needed, and then when I'm done I can see if it can be "cleaned up" by moving initilizations, exit conditions, and/or increment code inside the for's parentheses.
A situation where you always need to run a piece of code once, and depending on its result, possibly more times. The same can be produced with a regular while loop as well.
rc = get_something();
while (rc == wrong_stuff)
{
rc = get_something();
}
do
{
rc = get_something();
}
while (rc == wrong_stuff);
It's as simple as that:
precondition vs postcondition
while (cond) {...} - precondition, it executes the code only after checking.
do {...} while (cond) - postcondition, code is executed at least once.
Now that you know the secret .. use them wisely :)
do while is if you want to run the code block at least once. while on the other hand won't always run depending on the criteria specified.
I see that this question has been adequately answered, but would like to add this very specific use case scenario. You might start using do...while more frequently.
do
{
...
} while (0)
is often used for multi-line #defines. For example:
#define compute_values \
area = pi * r * r; \
volume = area * h
This works alright for:
r = 4;
h = 3;
compute_values;
-but- there is a gotcha for:
if (shape == circle) compute_values;
as this expands to:
if (shape == circle) area = pi *r * r;
volume = area * h;
If you wrap it in a do ... while(0) loop it properly expands to a single block:
if (shape == circle)
do
{
area = pi * r * r;
volume = area * h;
} while (0);
The answers so far summarize the general use for do-while. But the OP asked for an example, so here is one: Get user input. But the user's input may be invalid - so you ask for input, validate it, proceed if it's valid, otherwise repeat.
With do-while, you get the input while the input is not valid. With a regular while-loop, you get the input once, but if it's invalid, you get it again and again until it is valid. It's not hard to see that the former is shorter, more elegant, and simpler to maintain if the body of the loop grows more complex.
I've used it for a reader that reads the same structure multiple times.
using(IDataReader reader = connection.ExecuteReader())
{
do
{
while(reader.Read())
{
//Read record
}
} while(reader.NextResult());
}
I can't imagine how you've gone this long without using a do...while loop.
There's one on another monitor right now and there are multiple such loops in that program. They're all of the form:
do
{
GetProspectiveResult();
}
while (!ProspectIsGood());
I like to understand these two as:
while -> 'repeat until',
do ... while -> 'repeat if'.
I've used a do while when I'm reading a sentinel value at the beginning of a file, but other than that, I don't think it's abnormal that this structure isn't too commonly used--do-whiles are really situational.
-- file --
5
Joe
Bob
Jake
Sarah
Sue
-- code --
int MAX;
int count = 0;
do {
MAX = a.readLine();
k[count] = a.readLine();
count++;
} while(count <= MAX)
Here's my theory why most people (including me) prefer while(){} loops to do{}while(): A while(){} loop can easily be adapted to perform like a do..while() loop while the opposite is not true. A while loop is in a certain way "more general". Also programmers like easy to grasp patterns. A while loop says right at start what its invariant is and this is a nice thing.
Here's what I mean about the "more general" thing. Take this do..while loop:
do {
A;
if (condition) INV=false;
B;
} while(INV);
Transforming this in to a while loop is straightforward:
INV=true;
while(INV) {
A;
if (condition) INV=false;
B;
}
Now, we take a model while loop:
while(INV) {
A;
if (condition) INV=false;
B;
}
And transform this into a do..while loop, yields this monstrosity:
if (INV) {
do
{
A;
if (condition) INV=false;
B;
} while(INV)
}
Now we have two checks on opposite ends and if the invariant changes you have to update it on two places. In a certain way do..while is like the specialized screwdrivers in the tool box which you never use, because the standard screwdriver does everything you need.
I am programming about 12 years and only 3 months ago I have met a situation where it was really convenient to use do-while as one iteration was always necessary before checking a condition. So guess your big-time is ahead :).
It is a quite common structure in a server/consumer:
DOWHILE (no shutdown requested)
determine timeout
wait for work(timeout)
IF (there is work)
REPEAT
process
UNTIL(wait for work(0 timeout) indicates no work)
do what is supposed to be done at end of busy period.
ENDIF
ENDDO
the REPEAT UNTIL(cond) being a do {...} while(!cond)
Sometimes the wait for work(0) can be cheaper CPU wise (even eliminating the timeout calculation might be an improvement with very high arrival rates). Moreover, there are many queuing theory results that make the number served in a busy period an important statistic. (See for example Kleinrock - Vol 1.)
Similarly:
DOWHILE (no shutdown requested)
determine timeout
wait for work(timeout)
IF (there is work)
set throttle
REPEAT
process
UNTIL(--throttle<0 **OR** wait for work(0 timeout) indicates no work)
ENDIF
check for and do other (perhaps polled) work.
ENDDO
where check for and do other work may be exorbitantly expensive to put in the main loop or perhaps a kernel that does not support an efficient waitany(waitcontrol*,n) type operation or perhaps a situation where a prioritized queue might starve the other work and throttle is used as starvation control.
This type of balancing can seem like a hack, but it can be necessary. Blind use of thread pools would entirely defeat the performance benefits of the use of a caretaker thread with a private queue for a high updating rate complicated data structure as the use of a thread pool rather than a caretaker thread would require thread-safe implementation.
I really don't want to get into a debate about the pseudo code (for example, whether shutdown requested should be tested in the UNTIL) or caretaker threads versus thread pools - this is just meant to give a flavor of a particular use case of the control flow structure.
This is my personal opinion, but this question begs for an answer rooted in experience:
I have been programming in C for 38 years, and I never use do / while loops in regular code.
The only compelling use for this construct is in macros where it can wrap multiple statements into a single statement via a do { multiple statements } while (0)
I have seen countless examples of do / while loops with bogus error detection or redundant function calls.
My explanation for this observation is programmers tend to model problems incorrectly when they think in terms of do / while loops. They either miss an important ending condition or they miss the possible failure of the initial condition which they move to the end.
For these reasons, I have come to believe that where there is a do / while loop, there is a bug, and I regularly challenge newbie programmers to show me a do / while loop where I cannot spot a bug nearby.
This type of loop can be easily avoided: use a for (;;) { ... } and add the necessary termination tests where they are appropriate. It is quite common that there need be more than one such test.
Here is a classic example:
/* skip the line */
do {
c = getc(fp);
} while (c != '\n');
This will fail if the file does not end with a newline. A trivial example of such a file is the empty file.
A better version is this:
int c; // another classic bug is to define c as char.
while ((c = getc(fp)) != EOF && c != '\n')
continue;
Alternately, this version also hides the c variable:
for (;;) {
int c = getc(fp);
if (c == EOF || c == '\n')
break;
}
Try searching for while (c != '\n'); in any search engine, and you will find bugs such as this one (retrieved June 24, 2017):
In ftp://ftp.dante.de/tex-archive/biblio/tib/src/streams.c , function getword(stream,p,ignore), has a do / while and sure enough at least 2 bugs:
c is defined as a char and
there is a potential infinite loop while (c!='\n') c=getc(stream);
Conclusion: avoid do / while loops and look for bugs when you see one.
while loops check the condition before the loop, do...while loops check the condition after the loop. This is useful is you want to base the condition on side effects from the loop running or, like other posters said, if you want the loop to run at least once.
I understand where you're coming from, but the do-while is something that most use rarely, and I've never used myself. You're not doing it wrong.
You're not doing it wrong. That's like saying someone is doing it wrong because they've never used the byte primitive. It's just not that commonly used.
The most common scenario I run into where I use a do/while loop is in a little console program that runs based on some input and will repeat as many times as the user likes. Obviously it makes no sense for a console program to run no times; but beyond the first time it's up to the user -- hence do/while instead of just while.
This allows the user to try out a bunch of different inputs if desired.
do
{
int input = GetInt("Enter any integer");
// Do something with input.
}
while (GetBool("Go again?"));
I suspect that software developers use do/while less and less these days, now that practically every program under the sun has a GUI of some sort. It makes more sense with console apps, as there is a need to continually refresh the output to provide instructions or prompt the user with new information. With a GUI, in contrast, the text providing that information to the user can just sit on a form and never need to be repeated programmatically.
I use do-while loops all the time when reading in files. I work with a lot of text files that include comments in the header:
# some comments
# some more comments
column1 column2
1.234 5.678
9.012 3.456
... ...
i'll use a do-while loop to read up to the "column1 column2" line so that I can look for the column of interest. Here's the pseudocode:
do {
line = read_line();
} while ( line[0] == '#');
/* parse line */
Then I'll do a while loop to read through the rest of the file.
Being a geezer programmer, many of my school programming projects used text menu driven interactions. Virtually all used something like the following logic for the main procedure:
do
display options
get choice
perform action appropriate to choice
while choice is something other than exit
Since school days, I have found that I use the while loop more frequently.
One of the applications I have seen it is in Oracle when we look at result sets.
Once you a have a result set, you first fetch from it (do) and from that point on.. check if the fetch returns an element or not (while element found..) .. The same might be applicable for any other "fetch-like" implementations.
I 've used it in a function that returned the next character position in an utf-8 string:
char *next_utf8_character(const char *txt)
{
if (!txt || *txt == '\0')
return txt;
do {
txt++;
} while (((signed char) *txt) < 0 && (((unsigned char) *txt) & 0xc0) == 0xc0)
return (char *)txt;
}
Note that, this function is written from mind and not tested. The point is that you have to do the first step anyway and you have to do it before you can evaluate the condition.
Any sort of console input works well with do-while because you prompt the first time, and re-prompt whenever the input validation fails.
Even though there are plenty of answers here is my take. It all comes down to optimalization. I'll show two examples where one is faster then the other.
Case 1: while
string fileName = string.Empty, fullPath = string.Empty;
while (string.IsNullOrEmpty(fileName) || File.Exists(fullPath))
{
fileName = Guid.NewGuid().ToString() + fileExtension;
fullPath = Path.Combine(uploadDirectory, fileName);
}
Case 2: do while
string fileName = string.Empty, fullPath = string.Empty;
do
{
fileName = Guid.NewGuid().ToString() + fileExtension;
fullPath = Path.Combine(uploadDirectory, fileName);
}
while (File.Exists(fullPath));
So there two will do the exact same things. But there is one fundamental difference and that is that the while requires an extra statement to enter the while. Which is ugly because let's say every possible scenario of the Guid class has already been taken except for one variant. This means I'll have to loop around 5,316,911,983,139,663,491,615,228,241,121,400,000 times.
Every time I get to the end of my while statement I will need to do the string.IsNullOrEmpty(fileName) check. So this would take up a little bit, a tiny fraction of CPU work. But do this very small task times the possible combinations the Guid class has and we are talking about hours, days, months or extra time?
Of course this is an extreme example because you probably wouldn't see this in production. But if we would think about the YouTube algorithm, it is very well possible that they would encounter the generation of an ID where some ID's have already been taken. So it comes down to big projects and optimalization.
Even in educational references you barely would find a do...while example. Only recently, after reading Ethan Brown beautiful book, Learning JavaScript I encountered one do...while well defined example. That's been said, I believe it is OK if you don't find application for this structure in you routine job.
It's true that do/while loops are pretty rare. I think this is because a great many loops are of the form
while(something needs doing)
do it;
In general, this is an excellent pattern, and it has the usually-desirable property that if nothing needs doing, the loop runs zero times.
But once in a while, there's some fine reason why you definitely want to make at least one trip through the loop, no matter what. My favorite example is: converting an integer to its decimal representation as a string, that is, implementing printf("%d"), or the semistandard itoa() function.
To illustrate, here is a reasonably straightforward implementation of itoa(). It's not quite the "traditional" formulation; I'll explain it in more detail below if anyone's curious. But the key point is that it embodies the canonical algorithm, repeatedly dividing by 10 to pick off digits from the right, and it's written using an ordinary while loop... and this means it has a bug.
#include <stddef.h>
char *itoa(unsigned int n, char buf[], int bufsize)
{
if(bufsize < 2) return NULL;
char *p = &buf[bufsize];
*--p = '\0';
while(n > 0) {
if(p == buf) return NULL;
*--p = n % 10 + '0';
n /= 10;
}
return p;
}
If you didn't spot it, the bug is that this code returns nothing — an empty string — if you ask it to convert the integer 0. So this is an example of a case where, when there's "nothing" to do, we don't want the code to do nothing — we always want it to produce at least one digit. So we always want it to make at least one trip through the loop. So a do/while loop is just the ticket:
do {
if(p == buf) return NULL;
*--p = n % 10 + '0';
n /= 10;
} while(n > 0);
So now we have a loop that usually stops when n reaches 0, but if n is initially 0 — if you pass in a 0 — it returns the string "0", as desired.
As promised, here's a bit more information about the itoa function in this example. You pass it arguments which are: an int to convert (actually, an unsigned int, so that we don't have to worry about negative numbers); a buffer to render into; and the size of that buffer. It returns a char * pointing into your buffer, pointing at the beginning of the rendered string. (Or it returns NULL if it discovers that the buffer you gave it wasn't big enough.) The "nontraditional" aspect of this implementation is that it fills in the array from right to left, meaning that it doesn't have to reverse the string at the end — and also meaning that the pointer it returns to you is usually not to the beginning of the buffer. So you have to use the pointer it returns to you as the string to use; you can't call it and then assume that the buffer you handed it is the string you can use.
Finally, for completeness, here is a little test program to test this version of itoa with.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int n;
if(argc > 1)
n = atoi(argv[1]);
else {
printf("enter a number: "); fflush(stdout);
if(scanf("%d", &n) != 1) return EXIT_FAILURE;
}
if(n < 0) {
fprintf(stderr, "sorry, can't do negative numbers yet\n");
return EXIT_FAILURE;
}
char buf[20];
printf("converted: %s\n", itoa(n, buf, sizeof(buf)));
return EXIT_SUCCESS;
}
I ran across this while researching the proper loop to use for a situation I have. I believe this will fully satisfy a common situation where a do.. while loop is a better implementation than a while loop (C# language, since you stated that is your primary for work).
I am generating a list of strings based on the results of an SQL query. The returned object by my query is an SQLDataReader. This object has a function called Read() which advances the object to the next row of data, and returns true if there was another row. It will return false if there is not another row.
Using this information, I want to return each row to a list, then stop when there is no more data to return. A Do... While loop works best in this situation as it ensures that adding an item to the list will happen BEFORE checking if there is another row. The reason this must be done BEFORE checking the while(condition) is that when it checks, it also advances. Using a while loop in this situation would cause it to bypass the first row due to the nature of that particular function.
In short:
This won't work in my situation.
//This will skip the first row because Read() returns true after advancing.
while (_read.NextResult())
{
list.Add(_read.GetValue(0).ToString());
}
return list;
This will.
//This will make sure the currently read row is added before advancing.
do
{
list.Add(_read.GetValue(0).ToString());
}
while (_read.NextResult());
return list;
I have a large project in C# (.NET 2.0) which contains very large chunks of code generated by SubSonic. Is a try-catch like this causing a horrible performance hit?
for (int x = 0; x < identifiers.Count; x++)
{decimal target = 0;
try
{
target = Convert.ToDecimal(assets[x + identifiers.Count * 2]); // target %
}
catch { targetEmpty = true; }}
What is happening is if the given field that is being passed in is not something that can be converted to a decimal it sets a flag which is then used further along in the record to determine something else.
The problem is that the application is literally throwing 10s of thousands of exceptions as I am parsing through 30k records. The process as a whole takes almost 10 minutes for everything and my overall task is to improve that time some and this seemed like easy hanging fruit if its a bad design idea.
Any thoughts would be helpful (be kind, its been a miserable day)
thanks,
Chris
Using exceptions for control flow is generally a bad practice (exactly because of the poor efficiency that you're observing). What type of data do you need to convert to decimal? Could you use TryParse method or some other method that doesn't throw exception if the input is not in the expected format?
Decimal.TryParse method should do the trick if you're parsing strings as it reports failure by returnning false:
decimal d;
if (Decimal.TryParse(str, out d))
// Ok, use decimal 'd'
else
// Failed - do something else
That is a truly horrible looking piece of code. In general exceptions should only be used to capture unexpected results. The fact that you are getting lots of exceptions means that this is a common condition that should become part of the intrinsic logic.
decimal.TryParse would be a far better option here and I would suggest caching the value of identifiers.Count * 2 as well (not sure if compiler will optimise that)
There's a TryParse for Decimal as well. It avoids the exception and uses a bool instead to signal success/failure.
It's scary looking code, and you're getting good suggestions on how to fix it.
If you want to know if those exceptions are costing you a big percentage of time, there's a simple way to find out.
Just pause it about 10 times, and each time examine the call stack. If the exceptions are costing some percentage of time like, say, 50%, then you will see it in the process of throwing or catching them on roughly that percent of pauses.