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?
That is pure Flamebait.
Java is a language which benefits more than most from performance profiling, in that
it is very easy to write inefficient code, because the mapping from code to actual
execution is not always very clear.
This is a strength, and a weakness. The degree of abstraction from the underlying
machine is high. This results in quite intelligible code, and an ease of coding complex
and abstract tasks. It also results in it being quite possible to write apparently
simple looking code which ends up executing in a very complex way.
Profiling will expose the gross inefficiencies, and allow them to be corrected.
It will never be possible to write as efficiently (execution time), as
in a more direct language, but the coding efficiency (programming time) is quite good,
and for a lot of applications that matters a lot more. It also has a lot of
cross platform capabilities (not perfect I concede).
I prefer writing code where I can see the bits and bytes (i.e. not Java), but
to put down Java in such an off hand way is unjustified.
Download jrat here
I've used it many times, and it's helped me find horrible Hibernate queries, Lucene bottlenecks, Batik rendering pipeline issues. It is fantastic.
[% slash_sig_val.text %]
That's simply not true. I work on a large Java project that deals with a lot of matrix intensive work. Our Java code has been rigorously architected, engineered, and optimized. The matrix code in particular (where the majority of our processing time is spent) is far superior in Java than it was in C or C++. Every programming language has its place, use the one that suites your needs. Profiling most any code can reveal useful information.
You're implying that there are languages (other than Java) that don't ever require profiling which is simply rediculous.
While I do agree that for the most speed-intensive programs you need C, it isn't as bad as you seem to make it seem either. In many common algorithm tests, a JIT compiled Java program runs just as fast as its C equivalent. Also, the fact that Java is 'over 10 years old' is irrelevant, because C is over 30 years old. The fact remains that while a low-level is required for very intensive programs, in many applications the fastest program is not a necessity. This is often the case when you need to write a program where the database is a much larger bottleneck. Many companies use Java for speed-to-solution, and in this parameter Java easily outdoes C.
.NET wrappers is irrelevant. You can use DirectX with unmanaged code as well, it is just that it has wrappers available so that if you wanted to use it with C# or VB.NET, you can. It was NOT re-written in C# internally or anything like that, because that WOULD deliver a fair performance hit.
Also, your mention of DirectX having
Anyways, I feel every programming language has its place somewhere. To say that one language is worse than another one in every aspect is more likely to be false than true since its an absolute statement.
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
Yes. Batik, for example, is written in Java. Admittedly, it is much slower than Inkview in starting up and opening a file, or opening another file once started, but on the other hand, it supports filters (which inkview doesn't) and clips properly at image edge (inkview doesn't), and supports scripts and other niceties.
X86 assembly has been around since 1978, and even on a P4 3.5GHz computer you have to optimize to run well. I guess that means that assembly equals bad performance. It couldn't possibly be because "simple application" nowadays means something different than 10 years ago.
Not to say that Java is neccessarily a fast language, but saying that "you have to optimize to get good performance" is true for any programming language.
Forget magic. Any technology distinguishable from divine power is insufficiently advanced.
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 agree totally. Java is dead. We just have to get the message through to the huge numbers of organizations and developers who depend on the technology to get their jobs done. Oh, and then we have to come up with something better to replace it. Give me a little while... ;)
These two tools aren't profilers, there anaylsis tools. hpjmeter uses the output generated by hprof (the profiler that ships with the JDK) and the other tool you mentioned analyzes the garbage collection log. The problem with traditional tools like hprof is that 1: they require native components and 2: they don't let you turn the profiler on and off at runtime and 3: they profile everything -- even things that you as a developer can't change.
Just raise the taxes on crack.
"Quick! Name a successful Java program. Nope. I can't think of one either."
.NET.
Gmail. It uses Java for almost all of its back end. In fact almost all of Google's large scale web applications use Java in some form. Python is also used extensively however, it's generally used for simple scripts and smaller applications. Tons of websites use Java extensively and people like you are just too dumb to realize it. If you do online banking it's almost guaranteed that the website is using server side Java.
In terms of client side applications there's; Azureus, LimeWire, Eclipse, Netbeans, Intellij IDEA, Yahoo Site Builder, ZipCreator, Summit Groupware, jEdit, SmartCVS, NeoOffice etc. etc. Just because you don't use them doesn't mean that they're not there. The truth is that most people only use a very select few programs and these programs are often using code bases that are over 10 years old (ie. Microsoft Office, Outlook, Internet Explorer etc.). Then there's all the enterprise applications that are written in Java.... In the enterprise world Java is dominant and the only real competitor is
Never use the word "best-of-breed" again. Or else.
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.
The Java code will probably be more maintainable and less error-prone, but to suggest that it will outperform optimized C code is patently ridiculous.
Well, you are to narrow minded. Your example about arrays is strictly correct, but modern Java jits REMOVE the array bounds check if they can prove that the index will never be out of bounds. So this arguemnt does not hold
So I only picked the one above.
Please: why the heck do you think that a linked list traversal in Java MUST be slower than "optimized" C code? Whatever "optimized" in that context may mean?
Just because Java has an "not null" check?
Sorry, but sentences like this: because the structure of the java language is unable to deal with it as efficiently as the structure are complete nonsense. Java has only a few runtime checks. Those take not much time. Often during Jit compiling and Hot Spot optimization those checks can get removed, and are removed. At that stage the code is as efficient as C.
Your whole argument chain is not taking into account modern compiler technologies. In fact languages like Haskell or Occaml or Self or Erlang have prooven that OO and functional languages can be transformed to more efficient code than C. C is just transformed "structure" by "structure" into assembelr and is then fix.
Modern compilers do much more controll flow and data analysises and inline much more. The above languages do that mainly even static at compile time, and Self and Java during Hot Spot analysis at runtime. They basicly try to attempt what template metaprogramming does for C++, and they succeede in that (google
angel'o'sphere
Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
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++.