• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Most common costliest Elements of Java

 
Ranch Hand
Posts: 60
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What are the most common costliest elements/processes of Java programming in terms of performance? I hear casting is one of them. Why is it costly and how do we circumvent or improve on it?
------------------
~James Baud
Talk, does not cook rice. - Chinese Proverb
 
Author
Posts: 6055
8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, the best answer is to pick up a copy of Peter Hagger's book "Practical Java" or Jack Shirazi's book"Java Performance Tuning." (I suppose other books work, too, but I haven't seen their author's post here ;-)
Some types of casting isn't avoidable, such as castig to meed method signatures. A common example is storing items in vectors. Everytime you get an item from a vector, it comes back as an Object. You may then need to downcast it. If you find yourself doing this often, ask youself if a vector is really the only option. Maybe an array or other data structure is a better option.
The tradeoff with an array for example, is the risk of an array out of bounds exception. So maybe you create an array far bigger than you think you'll need (to avoid resizing), and keep a pointer, or a list of open slots. You then re-implemt much of what a vector does, but with your own code. The cost is your own code complexity. The advantage is that your vector class may use your object Foobar, instead of java.lang.Object, and so you avoid the cast. If reading from a vector is very common, this may be worthwhile.
In Peter Haggar's talk on Exceptions at JavaOne this past year, he mentioned that some poeple, insead of catching exceptions ExpA, ExpB, and ExpC thrown by a try block, try to catch a general Excetpion, and the cast to the right type. (I can't believe people did that!) It's much more efficent to handle each type seperately.
In some of my code, we pass around Message objects, serialized over the network. We then deserialize them, and handle different Messages differently. I coudl have deserialized, and cast to the different types, but that would have been costly. Instead, we include a special tag in every Message class which identifies which type it is (the tag could just be the class name). So rather than use casting, I can use an if statement, which is much faster.

Other costly processes include:
1) Modifying immutable objects (most often Strings). Because the objects are immutable, "changes" to them actually create new obects. In the case of Strings, use StringBuffer.

2) Object creation. Creating new objects is rather costly. In performence critical code, you can try object reuse--reinitializing an object with a given state, rather then creating a new one, basically using an object pool. This won't work in all cases, though.
Another variation is to use constants for objects--not just primatives. I found an example of this recently in GUI code some people at my company wrote. The code required the creation and re-creation of a number of GUI objects. This was unavoidable. However, each time the new objectwas created, a new Font object was created to set the object's font property. It was the same font each time and would never change! By simply making a static final Font object, we were able to reuse one object, instead of creating dozens.

3) Exceptions. Because exceptions are objects, they are costly. If the error is something likely to happen, try to use an if statement to check for it, since its faster--although this may result in less readable code. Only use exceptions for unlikely (or "exceptional") cases. (I must attribute this, too, to Peter Haggar's talk.)

I'm going to stop now, because otherwise I'll just start more or less quoting the books named above. I hope I didn't step on too many toes of those who have given talks and written books.
--Mark
hershey@vaultus.com
 
author
Posts: 106
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Man, my feet hurt! Just kidding Mark...good list.
Another costly thing is synchronizing too much code. If methods are synchronized unnecessarily, you limit the concurrency of code. You also increase the chances for deadlock, and there's nothing slower than that.
I don't know what the most expensive thing is, and it most likely varies depending on your JVM/JIT, but I would bet it's object creation (as Mark pointed out). Not only do you incur the cost of creating the object (which can be large), you also incur the cost of tracking it and most likely cleaning it up with the GC. Also, the cost of creating an object increases as the inheritance hierarchy gets deeper, and/or the object contains many other objects, or large objects, and the more code that is in the object's ctor.
Object creation costs can bite you especially when it's not obvious that objects are being created. Mark pointed out to be careful when "modifying" immutable objects. Of course you can't "modify" an immutable, but String and other immutables contain methods that pretend to modify them. String has methods concat(), replace(), subString(), toLowerCase(), toUpperCase(), that create new Strings.
Exception objects are actually more costly than "regular" objects. The reason is that each time an exception object is created, that is an object that inherits from Throwable, the Throwable ctor calls the native method fillInStackTrace(). This method walks the stack to gather the stack trace information for this exception object. Therefore, exception objects have this additional cost. In addition, using exceptions requires extra bytecode, exception tables to be generated in the .class file, and additional JVM machinery to route them around. Bottom line, use exceptions for error conditions, not for control flow.
I hope this helps,
Peter Haggar
------------------
author of: Practical Java
 
Ranch Hand
Posts: 89
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Is there any difference in cost between checking for checked vs. unchecked exceptions?
 
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Mark Herschberg:
Some types of casting isn't avoidable, such as castig to meed method signatures. A common example is storing items in vectors. Everytime you get an item from a vector, it comes back as an Object. You may then need to downcast it. If you find yourself doing this often, ask youself if a vector is really the only option. Maybe an array or other data structure is a better option.


Thank you, Mark, Peter -- very instructive.
I really wish generic types (templates) would come off the ground. It's a pity to have a nice collection framework hampered by the necessity to cast everything you pull out of it.
- Peter
 
Peter Haggar
author
Posts: 106
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Rob Acraman:
Is there any difference in cost between checking for checked vs. unchecked exceptions?


I assume you mean catching checked vs. unchecked exceptions? If so, there is no difference. The checked-ness or unchecked-ness of an exception is only a compile-time concern. They are handled the same at runtime by the VM.
Peter Haggar
------------------
author of: Practical Java
 
Bartender
Posts: 783
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would have to agree with Peter Haggar that object creation is one of the most (if not the most) expensive task for a JVM. Creating an object requires a lot of work on the JVM (allocating memory, keep track of it in the heap for GC, etc).
When I had to tune some piece of code, more likely than not, I would have to implement some type of object pooling technique. Especially if it's related to creating a lot of String objects.
Don't use synchronized methods if you don't have too. That's another performance killer. If you can use an ArrayList(), then do so rather than a Vector(), because the Vector is a thread safe collection it uses synchronized methods for all public access to the internal collection.
If you do have a collection, and the collection contains objects of the same type and the collection isn't going to change, than convert the collection to an array. This is great if you have access the objects inside the collections numerous times, because you don't pay the penalty to cast the object back to the correct type.
-Peter
 
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi there.
A lot of good tips and interesting remarks here. I would be very happy if somebody answered me on this too:
1) How do you track Object creation/deletion, garbage collection and other memory/resource allocating processes?
From some of the messages around it seems that programmers that seem to be more into this than I am, have difficulties with controlling (keeping track of) Object instances throughout program execution. Now, in my simple world, the general solution to this is to do nothing, as the gc eats it all when all refs/the last ref to that Object has a null value. (Similarly, when that Object is handled by the gc, all the refs that the Object itself contains, are set to null, or deleted, and the intances these point to are handled (that means deleted, right?) by the gc as well). I can understand that in some cases, when you want to reuse that variable/pointer dynamically in your code and it sometimes is assigned to a new Object, and sometimes not, that things may become somewhat more complicated but still... Well, anyway, are there some system functions that you can use during debugging for instance, that will report your Object/resource allocation during program flow?
2) What is a checked vs. an unchecked Exception?
I see one guy asks about differences between checked vs. unchecked Exceptions, and he even gets an answer on this. I didn't know there existed such a term. Anyone care to tell me what it is?
Thanks in advance,
Marius
 
Author
Posts: 71
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mark Herschberg writes;
In Peter Haggar's talk on Exceptions at JavaOne this past year, he mentioned that some poeple, insead of catching exceptions ExpA, ExpB, and ExpC thrown by a try block, try to catch a general Excetpion, and the cast to the right type. (I can't believe people did that!) It's much more efficent to handle each type seperately.
Although I agree with the efficency concerns, I am not at all bothered by people deciding to only catch Exception. I believe that there are two stressors and one mitigating factor working against catching each specific exception. The first is design, the second is readability.
Design: I was thinking object design but, this is more of a pattern of thinking that falls from object design and isn't really object design. So, if I'm not doing anything different with each of the exceptions, then I would argue that I only need to catch Exception. If I find that I need to handle a specific exception differently, then I will catch it.
Readability: This maybe more personal but, I find code littered with try catch blocks to be more difficult to read. Since I'm concerned about my own comfort rather than the computers, I like to make sure my code is readable.
Mitigating Factor: This is where we all agree. For the performance reasons already layed out, Exceptions should only be thrown in exceptional cases. Since I'm in an exceptional situation, performance is now of less importance to me. And if I'm throwing enough exceptions to impact the performance of my application, then I've got bigger problems to solve.
So I find that my try catch blocks mostly only catch Exception (or Throwable) because IMHO, the design and readability factors out weigh the potential performance hit.
I don't have Jack's book in hand to draw attention to specific sections but, I do believe that you'll find that he trys to balance design/performance issues.
------------------
 
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Marius Holm:
1) How do you track Object creation/deletion, garbage collection and other memory/resource allocating processes?
From some of the messages around it seems that programmers that seem to be more into this than I am, have difficulties with controlling (keeping track of) Object instances throughout program execution. Now, in my simple world, the general solution to this is to do nothing, as the gc eats it all when all refs/the last ref to that Object has a null value. (Similarly, when that Object is handled by the gc, all the refs that the Object itself contains, are set to null, or deleted, and the intances these point to are handled (that means deleted, right?) by the gc as well). I can understand that in some cases, when you want to reuse that variable/pointer dynamically in your code and it sometimes is assigned to a new Object, and sometimes not, that things may become somewhat more complicated but still... Well, anyway, are there some system functions that you can use during debugging for instance, that will report your Object/resource allocation during program flow?


The problem with letting GC take care of all of the objects you have created is that GC is very expensive, and basically your whole program comes to a standstill while GC does its thing. To get an idea of how many objects your program creates, get a copy of OptimizeIt. It's very easy to use and can profile your already-running program with almost no configuration.


2) What is a checked vs. an unchecked Exception?
I see one guy asks about differences between checked vs. unchecked Exceptions, and he even gets an answer on this. I didn't know there existed such a term. Anyone care to tell me what it is?
[/B]


"Checked" exceptions: the compiler checks them to make sure that either they are caught or your method declares them in its "throws" clause. These are typically not bugs in your program, but arise due to external factors (file doesn't exist, network goes down, etc.)
"Unchecked" exceptions: the compiler doesn't enforce the catching or "throws"-declaration of these. They are derived from RuntimeException and typically indicate bugs in your program, such as running past the end of an array when you should have tested for it (ArrayIndexOutOfBoundsException).
- Susan
 
Peter Tran
Bartender
Posts: 783
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In Jan 2001 JavaReport, there is a really good article on check vs. non-check exceptions by Todd Lauinger.
-Peter
 
Mark Herschberg
Author
Posts: 6055
8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Wow, great thread.
Kirk:
You are correct. When all exceptions require the same response, you should just catch the one type, for size and readability. It was only when in the single catch, the coder than did a cast and branch, that the code was inefficient.
Peter:
From reading your book, I understand the cost of object creation, I was wondering if you had calculated any numbers. How many bytecodes are needed to create... an Object, Vector, JButton, etc?


Marius Holm wrote:
How do you track Object creation/deletion, garbage collection and other memory/resource allocating processes?


JavaReport recently (Jan 01, or maybe Dec 00) had an article entitled "Loitering Objects and Java Framework Design." The authors suggested than when creating framworks, the user should clearly define who is responsible for creating ad deleting objects used by the framework. It applies more or less to any interface. Whenever you create an object, ask youself who will use it, fo how long, and how they get rid of it. To put it another way, everytime you do an assignment, whether explicit or by a method call, make sure you know when and where that object reference gets removed. (This is a very high level description, so I can go into more details if this isn't clear.)

Note, also, that you can have memory leaks in Java. Basicaly, creating objects which never get reclaimed. One common way to do this is with static variables. Recall that static variables get created when the class is first loaded. If the JVM does not support class unloading, then, unless you explicitly remove the references held by the static objects, those objects can never get reclaimed--even if no instances of the class exist!

--Mark
hershey@vaultus.com
 
Peter Haggar
author
Posts: 106
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

where, this code:
Object o = new Object();
generates this bytecode:

I have used a zero element byte array as an object to lock on when implementing something I call multiple locks per object.
Peter Haggar
------------------
author of: Practical Java
[This message has been edited by Peter Haggar (edited January 17, 2001).]

[This message has been edited by Jim Yingst (edited January 18, 2001).]
 
Author
Posts: 96
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I recently saw an IBM document suggesting a rule of thumb that if you throw exceptions and enter the catch block in more than 1% of runs through a particular try-catch block, then this is a candidate for something that is not exceptional, and should be re-written so as not to throw exceptions.
I worked it out, and performance-wise its a fairly good rule.
------------------ http://www.JavaPerformanceTuning.com/
 
Peter Haggar
author
Posts: 106
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The bytecode in my previous post got mangled...I tried to fix it and made it worse. My apologies. Let me try again with something I just learned about angle brackets... If this doesn't look good, it has something to do with the comments I added to the right. BTW, the comments are generated by me, not the javap tool.
This code:
byte[] b = new byte[0];
generates the following bytecode:

This code:
Object o = new Object();
generates the following bytecode:

Peter Haggar
------------------
Senior Software Engineer, IBM
author of: Practical Java
 
Ranch Hand
Posts: 202
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Really informative.....
When an object implements the finalize() method, it is called before an object is reclaimed by the garbage collector.
Is it better to get an object to implement finalize than an explicit call to System.gc()

------------------
Suneel
 
Peter Haggar
author
Posts: 106
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The finalize method is advertised as a way to ensure non-memory resources are freed before the memory for an object is reclaimed. Because the GC only frees object memory, finalize provides a way to free other resources. However, because all objects are not guaranteed to be freed during the execution of your program, you cannot rely on the finalize method for an object being called and freeing these non-memory resources. Therefore, even though you code your finalize methods properly, you can still run out of non-memory resources even if the GC runs. This issue, and others like it are covered in my book.
Peter Haggar
------------------
Senior Software Engineer, IBM
author of: Practical Java
 
Suneel Setlur
Ranch Hand
Posts: 202
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Mr.Haggar
I hope I win the book.
Regards
Suneel
[This message has been edited by Suneel Setlur (edited January 19, 2001).]
 
reply
    Bookmark Topic Watch Topic
  • New Topic