- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
This code creates an infinite loop because idx is not incremented.
ED: This was my mistake, I fixed it ...
Admin
WOW. Tar and feathering for the devolopers that use this!
Admin
I'm stunned...
Admin
It's a good idea, but it's a new idea; <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>
therefore, I fear it and must reject it.. <o:p></o:p>
Admin
My guess is that Alex accidentally forgot to put the ++ in there.
Admin
I suspose it's useful if the constant of true changes anytime soon, but then you have the empty catch statement. Tsk. Tsk Tsk.
This programmer should be taken out back and SHOT.
Admin
Assuming it is idx++..
exceptions are faster than conditionals!!!1oneone
p.s. this captcha doesn't look that strong
Admin
assuming that it should be 'idx++'... I recall hearing that early Java (1.0?) was much more efficient to loop like this catching exceptions, than to do a typical for-loop. shrug
Admin
Can you expand on this? What exactly are you trying to say? That using exceptions in this manner is a good idea?
Admin
I've seen this pattern too. +o(
Admin
Out of curiousity, did you also hear an explanation for WHY that would be more efficient, let alone much more efficient?
Admin
Wha.... Th... Fu...
Admin
You know you suck when your code relies on an Exception being thrown. When exceptions become logic, don't they, by definition, cease to be exceptions?
Admin
Why is it so many developers insist on reinventing the wheel in the shape of a square or triangle?
Admin
Everyone's assuming there should be an idx++ in there... but you know, it could be even more frightening than that. It's entirely possible that displayProductInfo(prodnums[idx]) will also delete the item from the prodnums array.
Admin
I hearby dub this "expection handling".
Admin
I have seen this code before in a book efficient Java programming. It was provided as an example of very inefficient code.
Admin
Hm. That actually almost makes sense. Since Java automatically bounds-checks its arrays, checking to see if the array index is in bounds yourself is redundant. So it all comes down to whether the mechanism for throwing and catching an exception is faster than all those extra comparisons you'd be doing otherwise.
The thing that makes me skeptical is that exceptions in early Java were really slow. Maybe they've improved over the years; I haven't been keeping track. But in the old days, at least, every exception was a new object that the system had to allocate and construct.
Admin
It's faster because the array library that throws the exception must already be checking whether the index is in range or not. Adding another check in application code is just duplicating work.
(NB Not that I think programming this way is a good idea)
Admin
Eh, eitherway it isn't supposed to be an infinite loop right? That would be a WTF on a WTF
Admin
This pattern to loop and break on exception is similar to a VB pattern that was posted up a month or so ago.
Regardless, it is fun, especially since only one particular type of exception is caught. Suppose the indexer was hand-written... you could generate an overflow exception here...
Admin
I can't believe it took Alex this long to even come across this. These stupid uses of exception handling are everywhere. Sometimes I think its the "I just learned this" syndrome...other times it might be "you WILL handle exceptions" policy....but it could also be the "it's broken...fix it" mentality in which the exception is simply caught and ignored rather than attempting to discover (the blatantly obvious in this case) reason why it was thrown in the first place.
While stupid and annoying, and definitely worthy of WTFery, this isn't eyes-bleeding bad.
It does, at the very least, work. :p Unfortunately...so does the programmer that wrote it.
Admin
<font style="font-family: arial;" size="1">Is this java?
.Net has a native IndexOutOfRangeException, but not an IndexOutOfBoundException.
That doesn't mean you couldn't derive your own.
In any event, the avoidance of this "design" is on every "top 10 tips" article.
It's just so basic... [weeps in despair]
</font>
Admin
This programmer is a real genius! Really! Don't you all see, we have code that doesn't care how big the prodnums array is. No matter how it gets changed, or even if it was retrieved from a database, this code will always display every product. Not only that, you save the space needed by your size variable. Brillant!
Admin
Maximum of 2 comparisons ANDed together versus Try/Catch overhead... Hrm...not sure about that one.
Admin
God you people crack me up...I love when people give excuses like "it is faster" for examples like this. If this is how someone "optimizes" code then I feel sorry for their employer and coworkers. An extra if statement from checking if the index is past the range of elements is not going to see any noticeable performance.
That is almost as bad as the people who say that pre increment in a for loop is faster than post increment...ridiculous
Admin
My god man...your statement is brillant! Not only does it clearly and obviously state the point, but the appositive-using complex sentence does it in such a way that the kind of people you would want to understand it...wouldn't. But the rest of us would get to chuckle along with you. Well said, sir...well said.
Admin
Doesn't matter if it deleted the item from the array or not. The size of an array in Java is immutable so it would still be an infinite loop unless the called method intentionally threw an IndexOutOfBoundException.
More than likely Alex forgot the ++.
Admin
Plus, it really isn't faster - I tried. Even doing a while loop and having your own check instead of using for is significantly faster than exceptions. Java exception handling still seems to be slow. It might be faster on a different platform. On Java, it isn't.
Admin
I remember this kind of code given in a programming course. More of a "how you can abuse exceptions" example, not a "how you should write loops" chapter. I have a sneaky suspicion, people just picked up the book, copied the code sample, without reading the surrounding text. (no idea what book it was)
Admin
Except for the fact that it is, sometimes very significantly so. At least in C++. If you are iterating over a map or something like that, the iterator is actually a fairly complex object. So making needless copies of it by using the post-increment operator is a bad idea.
If there was much of a readability difference between the two, I'd say the language was broken. But there isn't. So I think a style change to prefer pre-increment over post-increment in any case where either could be used is a good idea.
Admin
That's WAY too much code...
<FONT color=#0000ff><FONT face="Courier New" size=2>try</FONT></FONT>
<FONT face="Courier New" size=2>{</FONT>
<FONT size=2><FONT face="Courier New"><FONT color=#0000ff> for</FONT>(<FONT color=#0000ff>int </FONT>idx=0; ;displayProductInfo(prodnums[idx++]));</FONT></FONT>
<FONT face="Courier New" size=2>}</FONT>
<FONT size=2><FONT face="Courier New"><FONT color=#0000ff>catch</FONT>(IndexOutOfBoundException ex)</FONT></FONT>
<FONT face="Courier New" size=2>{</FONT>
<FONT color=#008000><FONT face="Courier New" size=2> // nil (Brillant)</FONT></FONT>
<FONT face="Courier New" size=2>}</FONT>
What a great way to handle flow control [8-|]
Admin
Also, notice that this blindingly efficient programmer somehow overlooked something!
displayProductInfo(prodnums[idx]); idx++;
could be:
displayProductInfo(prodnums[idx++]);
Admin
You know, I think Python does something like this internally when you use an iterator object - it signals the end-of-list by throwing an exception.
And it looks like I'm right. See http://www.python.org/doc/2.4.1/lib/typeiter.html
Admin
Uh, it is faster. Trivially so, but when there is no downside to using pre-increment (other than learning a new style) and a minor benefit, why would you ever not?
Admin
Yeah. Now if they only had some 50 million products so they could take advantage of this point where "optimization" might start to be faster.
Admin
Hilarious!
Admin
Are you saying it's faster to do:
for (int i = 0; i < x; i++) { statements; }
Than to do:
for (int i = 0; i < x; i++) { statements; }
???
I can't believe that any compiler wouldn't create exactly the same native code for this code (in C/C++/C#/Java/anything else that compiles to native/byte code).
Admin
dammit.. the second statement is supposed to be:
for (int i = 0; i < x; ++i) { statements; }
Admin
<FONT face="Courier New" size=2>i have seen this happen. let's call it a consequence of our times. as someone quite dear to me once said: "average intelligence, while good, still implies that half of those surveyed are below its threshold." cut and paste order(N) line switch statements, parsing via assumption, and the raping of exceptions are spawned in multitude everytime the VB school down the street opens its doors.</FONT>
<FONT face="Courier New" size=2>in my country, a sad majority of people listen to AM radio, read books by danielle steele, and have interpreted genesis to reach the conclusion the snake turned into tyranosaurus rex and leapt out of the tree of knowledge after adam's fall. when you expect these people to employ 'logic' to solve a computational problem, hilarity ensues.</FONT>
Admin
Typically,I have found that programmers who spend hours justifying and optimizing and fretting over things like this are typically the same people who do things like bringing back all rows from a database table across a network just to return the count.
Admin
Assuming this is Java (which it looks like to me), it is impossible for that to happen. displayProductInfo will be given a copy of the pointer to prodnums[idx], not the same pointer that the loop uses. The method would have no knowledge of the array its parameter comes from. Also, arrays are not dynamic so you can't really remove anything from any array (other than setting it to null.. which, again, displayProductInfo is unable to do).
Admin
No, because the java compiler automatically hoists the out-of-bound check outside the loop, assuming it knows the size of array beforehand.
IOW, it doesn't bound-check on every element access if it's capable of doing so, despite what you may like to believe.
Admin
pre-inc is (trivially, in the case of ints, but moreso in the case of complex objects) faster than post-inc.
The reason is
++i ==> i = i + 1; return(i);
i++ ==> tmp = i; i = i + 1; return(tmp);
Note the extra copy when using post-inc. For complex objects this extra copy could be significant.
Admin
I have had to code this way due to conditions beyond my control. For example:
<FONT face="Courier New"><FONT face="Courier New">The dolt that designed the Foo object provided no way to determin the max value that the idx var can have.</FONT>
<FONT face="Courier New">
</FONT></FONT>Admin
Yes, but then again no. In your particular example, no, they'll compile to the same code in nearly all cases. int is usually a primitive type, and compilers are intelligent enough to convert that to INC (i) or whatever the equivalent native/byte code is.
If, however, you're not using int, but using some class instead, then using ++i is probably a better idea. Because of this, it's generally said to use ++i for "increment only" operations, just to get into the habit of it.
Why is it better on classes? It has to do with the difference of return values from those operations.
++i : Increments i, returns the incremented value.
i++ : Increments i, but returned the value just before the increment.
In a class that uses these, the implementation of the first one will simply be to increment whatever, but the implementation of the last one will *usually* (not always) use a temporary variable to hold the value, increment it, then return the value of the temporary variable. Using a temp variable takes more memory (not much, probably) and is slower (by some insignificant, but measureable, amount).
So it's a good idea to get into the habit of using ++i instead of i++, but it's not actually faster in the most commonplace cases, where you're incrementing a primitive.
Admin
<FONT color=#000000>Correct me if im wrong... just had to test it. Not that I would ever use it!</FONT>
<FONT color=#008000 size=1> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.CreateArray()
Me.WTF()
Me.NonWTF()
End Sub
Private Sub CreateArray()
Dim x As Integer
For x = 0 To Me.Array.Length - 1
Me.Array(x) = "What the Fuk"
Next x
End Sub
Private Array(1000000) As String
Private Sub WTF()
Dim currentTickCount As Long = Now.Ticks
Try
Dim idx As Integer
Do While (True)
Me.displayProductInfo(Me.Array(idx))
idx += 1
Loop
Catch ex As IndexOutOfRangeException
End Try
Dim timeTaken As Long = Now.Ticks - currentTickCount
Dim timeTakenInSeconds As Double = timeTaken / TimeSpan.TicksPerSecond
Trace.WriteLine("WTF TOOK : " & timeTaken & " TICKS (" & timeTakenInSeconds & ")")
End Sub
Private Sub NonWTF()
Dim currentTickCount As Long = Now.Ticks
Dim x As Integer
For x = 0 To Me.Array.Length - 1
Me.displayProductInfo(Me.Array(x))
Next x
Dim timeTaken As Long = Now.Ticks - currentTickCount
Dim timeTakenInSeconds As Double = timeTaken / TimeSpan.TicksPerSecond
Trace.WriteLine("NON-WTF TOOK : " & timeTaken & " TICKS (" & timeTakenInSeconds & ")")
End Sub
Private Sub displayProductInfo(ByVal text As String)
End Sub</FONT>
<FONT color=#008000 size=1>WTF TOOK : 468750 TICKS (0.046875)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 468750 TICKS (0.046875)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 468750 TICKS (0.046875)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 468750 TICKS (0.046875)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 468750 TICKS (0.046875)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 468750 TICKS (0.046875)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 468750 TICKS (0.046875)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)
WTF TOOK : 312500 TICKS (0.03125)
NON-WTF TOOK : 312500 TICKS (0.03125)</FONT>
Admin
Maybe the title could have been Exceptional Code turns away in anticipation of the boos
Unfortunately, I have seen this in production code, and I immediately replaced it with an acceptable pattern. Fortunately, however, the developer idiot who did this is not here anymore!
Admin
That doesn't apply to Java, though (if this is, as I strongly suspect, Java), because you can't apply ++ to anything complex there.
It's only relevant to languages with operator overloading, like C++, and C# perhaps. (Not sure if you can overload ++.)
Admin
Guys, your discussion about exceptions being faster is moot.
The method being called in loop is named "displayProductInfo". This indicates that something GUI-related is going to happen, which will probably take about a billion times longer than checking whether the index is within bounds.
By the way: "Premature optimization is the root of all evil (or at least most of it) in programming.” — Donald Knuth