- 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
sorry but I have to call shennanigans. There's no way that pushing everything onto the stack in order to run the function isDebugEnabled takes fewer cycles than catting a string. I think this one is made up.
Admin
At least she didn`t used
Admin
The requirement is probably there more for a readable errorlog, which this code easily obliterates. I wonder how big this log gets, and if it gets rotated for freshness.
Admin
You're wrong. in the case of
Debug(var + "sdfjksdlj" +var);
the code HAS to call the debug procedure, and in order to do that, it HAS to perform the string concatenation to provide the argument.
However, in
if (debugon) {
Debug(var + "sdfjksdlj" +var);
}
if debug is off, the code for the call and concatenation are never executed.
This may seem like a minor point, until you realize that in most mature systems, there is practically a debug statement per line of actual code, and since a concatenation is at least as expensive as O(2n) where n=size of array/strings to concatenate, whereas the line of code it is documenting is only O(1) [A check to see if debug is off should only be around O(1)], the performance impact of debugging can be quite noticeable.
I was always very disappointed in JDK1.4's logging, in addition to the API being patently inferior to log4j, it did not introduce a base language capability to alleviate having to type if(log.debug) before all the log statements.
Admin
That log must look really nice after a while.. kind of flooded with
"The current log level is not debug. The message will not be logged."?
Admin
conditional compilation anyone?
Admin
Sucks because you can't switch log levels at runtime (think long-running server applications here).
Admin
Whether this is correct or not, I've tended to have the opinion that most business software doesn't need everything optimized completely. Since most business software will be added to later, it'll save more money later for the code to be clean.
Now, there are some optimizations that should be in there, but small stuff like this just isn't worth the time to go through the entire code base and add several lines of code to save a few processor cycles for an application that will run on a fairly powerful server.
Admin
What an idiot! She should have written:
logInfo("The current log level is not debug. The message will not be logged. Have a nice day!");
Noobs.Admin
The time required to execute a Debug statement is O(1) -- you are abusing the terminology here. O(1) means "constant execution time." Since the Debug statements tend to take in constant strings plus some variables of fixed length, their execution time is constant. Therefore, they are O(1), just like a line of code they may be documenting (lines of code can do things like string concatenation too, you know).
I do agree that "the performance impact of debugging can be quite noticeable," but so can the readability impact of putting "if (debugon)" in front of every Debug statement. It's just horrendous.
Therefore -- one should profile code and take pains to only use this measure where it's really necessary, and not make blanket assertions like "every debug statement should be wrapped in the if test." The latter is just bad practice; I have personally seen codebases that were already hard to read degraded by this justification for uglifying every single Debug statement.
Admin
Note that the code won't even compile. ;)
Admin
So let me get this straight. The code is so performance sensitive that a few string concatenations matter but not performance sensitive enough not to use Java in the first place?
Admin
Pretty much. I'm starting to think that the 2nd wtf is the code reviewer.
Admin
If performance is critical why are they using java?[:S]
Admin
Because Java programmers grow on trees and getting updates out the door would be faster than doing it in C/C++ and having to look for memory leaks.
Admin
So it's not feasible to use Java and still worry about performance?
What about your car? If your Camaro doesn't perform as optimal as a Corvette, just because it's not a Corvette, does that mean you're not concerned about it's performance? Maybe it doesn't need to run as well as a Corvette. Maybe it just needs to run as good as a Camaro.
Admin
So . . . she owns stock in one or more hard disk manufacturers' companies?
ok
dpm
Admin
Until you can show me an extensive benchmark that isn't slanted, you can go f--- yourself with this comment.
Admin
I am not agreeing with the snide attitude towards Java but assuming that cupofT's joke is based in reality and performance with Java will always be poor, your metaphor is completely idiotic. A more appropriate one would be, if you've got a red wagon that will always be travelling on flat land being pulled by a senior citizen (emptyset's grandmother perhaps), spending a lot of time worrying about the aerodynamics of the wagon is wasteful. Sure, it could make an improvement but at the speeds being achieved, a few seconds won't make a difference.
Perhaps if you think about it, you can realize where you went wrong in your great metaphor.
Sincerely,
Richard Nixon
Admin
No, I tried it, and when you concatenate 3 or more strings in JDK 1.5, the compiler uses StrinBuilder instead. I believe that in JDK 1.4 it uses StringBuffer.
Admin
Hey 'indeed',
Why is wrapping debug level log statements with an if-test bad practice? I'd much rather see that then see code that attempts to log something at debug when in any production environment the debug level isn't even enabled.
It's nice to save the cpu time to check to see if a particular logging level is enabled before spending the cpu time that it take to log a message that might never be logged anyway (depending on how the logger is configured).
Admin
Amen Mung Kee!!!
Admin
Exactly!
Admin
You do realize of course that there are numerous benchmarks these days that are showing Java as FASTER than C/C++, right?
Admin
I get it, the WTF is that they use java!!
the don't have conditional compiling
:P
Admin
should she have written
Admin
ack! what's the command to display code?
Admin
Hmm, someone's a little sensitve about Java's performance.
Admin
I'm genuinly intrigued. With all that C/C++ has going for it, how could Java pull off being faster (I assume you mean after the jvm starts up, or is that included)?
Admin
Well, for the statement of
debug("Foo" + int + " BAR" + String("bar"));
The time dif isn't great,
however consider printing results from complex objext
debug ("Input XML; " + inputXML.toString());
Given a large inputXML and a terrible placement inside an addElement method, this line was repsonbile for 20% of the load of an application, even when debug was off.
Admin
Does the word hotspot ring a bell to you? That call will get inlined when called enough times - resulting in something like if (false)...and that's faster that concatenating the strings together. If you run it only once though, it's hard to tell...
Admin
Absolutely. Modern JVMs, appropriately tuned, can be quite fast. Early java sucked wind. There have been several great leaps forward since then: HotSpot monitoring and JIT compiling are two, but generational garbage collection is, in my opinion, far and away the biggest single algorithm to speed up Java.
If anyone deploys a substantial java application without spending some time to choose the correct JVM parameters, they are the idiots, not the language.
Admin
Nope, just sensitive about conjecture.
Admin
In Java (Sun's JRE at least), the concatenation is done this way:
* Create an anonymous StringBuffer (one object allocation)
* Append every concatenation operand (five calls to StringBuffer.append() in our case)
* Call StringBuffer.toString() to obtain the resulting String
That's clearly much more expensive than calling one function, which is typically a getter that simply returns a boolean.
Besides, you might want to do more than a concatenation: compute statistics, access context information (e.g. user credentials), etc., which can potentially cost a lot. Of course, you may suggest that only such rare and expensive debug statements are wrapped, but 1) it's difficult to know the cost in advance, 2) it's easy to forget to wrap that one expensive debug, 3) the maintainer will probably forget to wrap the statement when it becomes expensive, and overall, regularity beats early optimization.
So, no shennanigans here, I've seen projects where such wrapping is policy, for every log statement at every log level. It might cost slightly more to create the code (Eclipse to the rescue, however), but it's far less expensive as far as runtime performance and maintaince costs go.
This might disturb you, but it's one of the differences between industrial code and artisanal code.
Admin
Bad policies won't stop bad programmers from writing bad code.
Admin
Wow. You are STUPID. I am amazed you're able to breathe on your own. Let's look at what I wrote, " I am not agreeing with the snide attitude towards Java but assuming that cupofT's joke is based in reality and performance with Java will always be poor," I stated that I don't agree with the assessment of Java's performance given in the first sentence! The first sentence! It doesn't get any closer to the top of the statement! That's the first one. Boy, you're really dumb.
Sincerely,
Richard Nixon
Admin
I have a hunch I'm going to catch hell for this, but I'll ask it anyway. I did mainly C/C++ (no Java) in college, but picked up Java at my first job out and now work for another company doing Java (so there are a lot of java specific things I haven't picked up yet).
This bit on JVM parameters, what all can you change and such? It's something you do in the JVM itself, right (not in the program)?
Admin
Alex, can we get a button which creates a post that quotes Donald Knuth, says that premature optimization is the root of all evil, and insists that performance tuning needs to be done in conjunction with a profiler rather than half-baked "coding standards"?
Admin
<FONT face="Courier New" size=2>this is a terrible analogy, and completely self-defeats the point you're trying to make. everyone knows a person who buys a bitchin' camaro isn't concerned about performance.</FONT>
Admin
amen!
Admin
Several things happen...
First, modern JVMs actively profile the code while it is running. Once the JVM decides what sections of code are important, they get compiled and run as native code rather than intrepreted. That gets us pretty close to C/C++ performance on a long running application like a server process.
Here is the second trick... Generally speaking when one compiles a C/C++ app, they choose a set of compiler options that will allow the executable to be run on a reasonable variety of machines. The JVM, however, knows that the bits of code that it compiles are only going to run on that very machine in the context of that very process. It is free to optimize for that environment. So while your C/C++ code is built to run on any pentium, the JVM can identify at runtime that you are using an AthlonXP and take advantage of every tweak possible.
The third trick is generational garbage collection. Generally speaking, objects have either very short or very long lifespans. Most objects will live for only a few lines of code. If they survive for more than a minute or two, they will likely survive for the entire duration of the program. Generational garbage collectors take advantage of this by dividing the heap into a New and Tenured Generation. Objects are created in the New generation, then moved to the tenured generation only after surviving a certain number of garbage collections. Different Garbage collection algorithms and schedules apply to each generation, drasticly reducing the overhead of gc. While there is still some overhead to gc, memory can also be reshuffled when needed, so optimal sized blocks can be allocated for buffers, sort areas, etc. C/C++ can't (without the help of some non-standard libraries) move objects around in memory to free appropriate size blocks.
Admin
Bad policies won't stop bad programmers from writing bad code.
Well, in my example, it might be perfectly valid in a debug setting to inspect the xml at the time the debug is called. What you failed to notice is that at run time, Java will compile the string statement, then send it to the debug method, thus running document.toString().
Wrapping this statement in isDebugEnabled(), prevents this.
It is a good policy to wrap evey debug statement in isDebugEnabled
Admin
This is recommended practice by the Apache people, who provide the most commonly used logging frameworks (commons-logging and log4j).
http://jakarta.apache.org/commons/logging/api/org/apache/commons/logging/Log.html
Performance is often a logging concern. By examining the appropriate property, a component can avoid expensive operations (producing information to be logged).
For example,
Admin
<FONT face="Courier New" size=2>an even better analogy is if your mom can suck off 37 guys in a parking lot and somebody videotapes it, you shouldn't worry about deciding to release it on vhs or beta.</FONT>
Admin
That one is good too.
Sincerely,
Richard Nixon
Admin
Whats especially fun, the log with logging turned off would look like:
Admin
In my experience, Java code is only faster when there are a large number of iterations through a method. Unlike the C compiler, the Java runtime environment can create optimized native code based on the frequency with which code paths are being followed. An executable which starts up, does little, and terminates is always going to be faster in C, because there is no need to set up the runtime environment as there is in Java. A server application that sits there and pushes through hundreds of transactions per second for months at a time, 24/7, is another story.
One has to be very careful comparing Java to C -- my first attempt to do so didn't take into account the multithreading of Java when outputting to the console, so Java looked twice as fast as C. (When I wrote to disk or discarded the formatted results, the benchmark showed identical times for Java and C.) Unless you want to test for multi-threaded performance (where Java tends to really shine), you have to make sure you're not accidentally giving Java an artificial edge.
I will grant that a sloppy coder can more easily create slow code in Java than C. Careless creation of many objects can drag peformance in the garbage collector, although recent versions handle this better.
Admin
wow, two different holy wars from a few lines of code. You know this is a huge WTF! This code is pretty funny though, guess she was told to put in debug statements after every single line of code no matter what.
Admin
My pet peeve is premature optimization. The biggest example of this is people barking about never using "abc" + "foo" + "bar" in Java. Sure its possible this is a big deal in your application, but come on. Unless this executed over 100k times per second, it probably not even close to being one of the critical performance issues.
Admin
This is good stuff too. Java has become very popular in the enterprise because enterprises have lots of long running applications. A decent team of programmers taking reasonable care can write long running Java programs that get better as they run. In contrast, reasonably well written C/C++ applications still occassionally get memory leaks, and the longer they run the greater the chance of memory fragmentation.