Build Your Own Java Performance Profiling Tool
An anonymous reader writes "IBM DeveloperWorks has an interesting look at creating a custom profiler using Java 5 and AOP. From the article: 'Profiling is a technique for measuring where software programs consume resources, including CPU time and memory. This article provides a list of best-of-breed features you might look for in an ideal profiler and explains why aspect-oriented techniques are well suited to achieving some of those features. It also introduces you to the JDK 5.0 agent interface and walks you through the steps of using it to build your own aspect-oriented profiler.'"
Byte-code hacking!?
Why not simply use AspectJ?
Seriously. Modifying a program to profile it?
I'd do that, but I'm a hybrid java developer/IT d00d. Most IT folk I know wouldn't touch a profiler with a 10-foot pole, much less write one and semi-build it into an app. This is a programming topic, not an IT one.
"Time flies like an arrow; fruit flies like a banana." --Groucho Marx
Using hprof and decent unit testing, you can work out where your problems are, I've found. All of this bytecode hacking and AOP stuff might show how l33t you are, but I'm not convinced it's really *needed*. Just my humble, uninformed opinion, of course, I'm very willing to hear from others. It could be that I'm just not working on sufficiently complex systems, or that I'm spending more time writing unit tests and pouring through hprof results than most folks.
I shouldn't really be replying, since you already said that all the specific instances which prove Java is slower don't matter - how could I argue with that ? However I would like to benefit from your obvious knowledge of the matter.
Also, please note that I didn't say "C/C++ is best", which you seem to be implying in your last paragraph - I was commenting in the context of the thread about Java vs C/C++ performance for matrix computations. I don't care about language wars, because obviously everyone who disagrees with me is wrong ... :-)
I have seen many claims about Java's performance, ranging from reasonable to absurd and ridiculous. For example:
I would love to share my opinion on these subjects some other time, but for this post they are irrelevant.
So, getting back to the subject. Obviously you agree that for the scenario I am describing, Java is slower than C. You contend that this results from "translating line by line from C into Java syntax". OK, enlighten me then. What is the Java-specific solution for keeping complex numbers in an array ? You can go wild - use any Java tool and technology. This is not an artifical scenario. The same problem exists for arrays of 2D or 3D coordinates, actually arrays of anything except primitive types, so if you present a solution I will be very grateful and even offer to buy you a beer ot two (or a dozen!).
We have a product that requires that profiling be done on a per-object basis. I'm not using the Java class transformer interface, but I am rewriting classfiles in a manner similar to hprof's bytecode instrumentation option (as opposed to the stack sampling option), using JVMTI.
JVMTI + JNI is pretty slick stuff. The source code to hprof comes with the JDK 1.5 release and is very informative, if overwhelming at first. If I instrument methods very selectively, the effect on runtime speed is minimal.
OTOH, trying to implement something like this for Perl (my favorite language) would be an exploration of pain the likes of which hasn't been experienced since people were broken on the wheel.
Very interesting read, thanks. It does show that in practice Java is fast enough, but it doesn't address my point. Too many things are omitted - restricted pointers, manual cache control, etc. I could delve into the specifics but I doubt anyone would read that om Slashdot.
For one the paper doesn't even mention the pointer chasing problem, which is inherent in the definition of the language. In Java almost everything is an object reachable through a pointer - accessing the object means stalling the CPU until the memory load of the pointer itself has completed. In loops this leads to easily measurable slowdown of at least 10x. A not that uncommon worst case scenario is an array of complex numbers or 3D coordinates. It is possible to work around the problem by using separate arrays for each component, but doing that in a high-level language like Java is a shame, not to mention extermely inconvenient.
As I said earlier, matrix calculations do not necessarily have this problem since they most likely use single-dimension arrays of primitive values. When the range checking is eliminated, there is no fundamental reason why accessing an array of primitive values should be any slower in Java compared to pure C. It all depends on how expensive optimizations can be done by the JITter at runtime. I doubt a JIT will do complex code reorganization optimizations, but it is possible.
Generally speaking, achieving high performance always requires fine-tuning, which is all but impossible in Java. You can't examine the generated code, you can't affect how the GC allocates memory, you can't selectively use assembler (JNI is too expensive), you can't selectively enable optimizations, you can't manually insert prefetch or cache control instructions in the generated code. You are stuck with what the current JIT does and there is no way to improve that. If experience has taught us anything, it is that there is always room for improvement. The problem is when you can't get to it.
All the performance problems specific to "C" mentioned in the referenced paper - e.g. aliased pointers, cache unfriendly memory allocation, etc - are solvable in C using restricted pointers, a custom memory allocator, etc. On the other hand the problems specific to Java cannot be fixed without modifying the language or at least the JIT compiler.
Let me put it another way. A hypothetical situation. Assume that you are an expert in both C and Java. You are given the task to write the fastest possible implementation of some algorithm. You are given plenty of time compared to the complexity of the algorithm. You can use either Java or C. When you are done, your implementation will be benchmarked against others (e.g. mine) and the author of the slower one will be killed. Which language would you choose ?
For the fanatics I would like to point that this has nothing to do with liking or disliking Java or saying that it is too slow. Java is a lot more robust and cost effective than C/C++.