|
Sponsored Links
Resources
Enterprise Java Research Library
Get Java white papers, product information, case studies and webcasts
|
News
News
News
|
Messages: 18
Messages: 18
Messages: 18
Printer friendly
Printer friendly
Printer friendly
Post reply
Post reply
Post reply
XML
XML
XML
|
 |
Java Performance vs. Readability
In "Declare Variables Inside or Outside a Loop," Dru Devore attacks a topic some carry over from other languages: the tendency to sacrifice readability for performance. While Mr. Devore uses a very (very!) simple performance test, it's a good start to a useful line of thought: Java doesn't usually need to be unreadable to perform well.
He wrote two tests: one allocated a primitive inside and outside of a simple loop, and the other allocated an object inside and outside of a similar loop. His conclusion was that for the primitive, it didn't matter, and for the object, it mattered some (in terms of allocating the instance).
His object example compares StringBuffer.setLength(0) to new StringBuffer(), which may or may not be very representative of normal code, but his point is that for primitives it doesn't matter, and for objects, it's probably better to reuse a previously allocated instance. This isn't exactly rocket science, but few people bother to actually find out what's going on under the covers.
Another aspect to consider is that the code he shows is pre-HotSpot. HotSpot will convert the code and optimize it as it's run; this code would have to execute a large number of times (1000 times, if memory serves) before the initial optimization runs, and as the code is used over and over again, might be re-optimized over time. Simple code like this might not be optimizable past a simple compilation, but more complex code would be.
Is there a way to test the HotSpot-generated code to see what's more efficient over long-running processes? What do you think about the whole issue?
|
|
Message #216201
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Re: Java Performance vs. Readability
I think this is a useful topic, as it comes up every day. Personally my view is that, in general, readability is more important than extracting the maximum performance out of code, because human confusion costs companies much more than slow applications in my opinion.
Obviously there are exceptions - there are no absolute rules in any business that I know of.
Devore also talks about 'small systems' - the habit of doing similar things in similar ways every time. In this case it is how he declares variables, object or primitive. Again I think this is a valuable habit.
A lot of the time, it's the small stuff that defines excellence. His points are worth considering IMO.
|
|
Message #216202
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Re: Java Performance vs. Readability
Considering how inexpensive memory and hardware and how good the compiler and VM is now does this really matter for business applications dealing with simple domain models? Therefore isin't it generally better to go fo readability and not worry about premature optimization?
Let's face it the amount of XML processing, database access that goes on in the average business application small optimizations are low down the list.
Of course there are exceptions. Large complex data structures, systems running research math problems or applications running on limited devices etc, etc, etc.
|
|
Message #216203
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Variables is variables
1. Object type variables and primitive type variables are not fundamentally different in Java. They both contain a value. I don't think it serves anyone any good to continue to talk as if they are. It just creates a lot of confusion.
2. Reusing a Object is not 'probably' better. In fact, it's probably not. For one, it screws with garbage collection. Your temporary Object could end up moving out of the young generation. In the specific case of StringBuffer, things get worse. Most likely, if the StringBuffer truly only needs a block scope, it's going to have a call to toString in the block somewhere (otherwise, why are you creating it?) When you call toString on a StringBuffer, the new String shares the underlying array with that StringBuffer. It also sets a flag saying that it's array is shared with a String. So when you reset the buffer length to 0 and start modifying it again, it is forced to allocate another array. In short, doing this doesn't buy you much of anything and can cause performance issues. I know it's a cliche but this is just another example of premature optimization.
3. Why is someone creating a blog entry about a topic that has been discussed ad nauseum years ago? Does Dru Devore believe this to be an unresolved question in the Java universe?
|
|
Message #216205
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Re: Java Performance vs. Readability
He wrote two tests: one allocated a primitive inside and outside of a simple loop, and the other allocated an object inside and outside of a similar loop. His conclusion was that for the primitive, it didn't matter ..
(I apologize for being pedantic)
int i;
Local variable declarations create no byte code (regardless of in or out of a loop), so one would expect that it would not influence performance.
i = 0;
Primitive assignment (as with many primitive operations) has such an unbelievably negligible impact on performance as to be almost entirely unmeasurable.
for the object, it mattered some
Object allocation differs widely from VM to VM, and is impacted by circumstances that are unlikely to be foreseen, such as object tenuring. While general performance trends can be established (and thus predicted), one cannot draw definitive conclusions without witnessing performance in a given environment (server, OS, VM, tuning parameters, load mix, etc.)
Peace,
Cameron Purdy Tangosol Coherence: Clustered Shared Memory for Java
|
|
Message #216211
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
as if readable is objective
This is a pretty crummy example of pitting readability vs performance, as it relies on one person's idea that it's more readable if variables used exclusively in the loop are declared outside the loop. I think just the opposite. And loops should be methods anyway, right?
|
|
Message #216215
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Patterns and idioms...
I'm all form routine code patterns and idioms. Things like using "c++" vs "c = c + 1". In the past, that was an actual performance blip back when you hade cheap compilers translating C in to 8080 assembly. Nowadays, not so much.
But the idiom stays, it habitual.
It's also good to get "good habits". If technique X is equivalent to technique Y, yet X is [faster, better, cheaper, smaller, etc.] than Y, then promote Y.
But nowadays, specifically with back office business progammers, it's pretty meaningless. With the modern JVMs, client vs server mode, JITs, machines with dozens of cores and CPU's, L1, L2, L3 caches, optimizing our code in the small is SO far detached from the "reality" of whatever that code actually ends up getting turned in to in terms of bits fed to a CPU, it's simply not worth the cognitive load to even think about it.
There was a time where folks would talk about the "sufficiently smart compiler". Where programmers could write straightforward code, and the compiler would magically be able to turn that readable, simple code into arcane, resequenced "optimal code". For very, very specific tasks, there will never be a smart enough compiler.
But for folks summing up order detail lines to prepare them for shipping? It's no contest. The compilers are GENIUS level for those mundane tasks.
Nowadays, whatever I stuff in to my x.java files are mere suggestions to the compilers, JVMs, CPUs, and operating systems. No matter what I put in there, those tools are going to mold that code in to their own image, and as long as the result that comes out matches the contract I specified in my code, the actual details of how that's done by the computer is pretty much irrelevant.
So, I'm going to continue writing code as I think it should be written to better clarify interpretaion of the problem domain as given in the specifications I'm implementing. I will cede very little simply to appease the computer, and will rather wait until the computer proves to me that whatever I gave it was the worst possible implementation possible, simply through demonstrated, miserable performance.
Much like my task as a programmer is to convert the intentions of the person creating the specification into performant, reasonable code, it is the compiler and runtimes jobs to take my scribbling and make it working well on the architectures I'm running upon.
Solid algorithms, solid design, these are what make programs efficient and performant. Moving variables around in source code is a waste of time. If I were writing 3D game engines for cell phones, then micro-managing the compiler can well pay off. But for shoving bits back and forth between databases, it's simply not worth the time or effort.
|
|
Message #216220
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
optimizing makes you feel like a true geek
There appear to be a whole school of java developers who are totally unaware of the changes made to the jvm over the past few years. I would say that the majority of the devs that I've met and work with still use "optimization" techniques that have been totally obsolete in java for some time now. My theory is that it makes them feel clever, so be damned with whether it actually helps or not.
Besides, I think 99% of good performance comes from good design. Architecture is really what you should be spending your grey matter on optimizing.
But nowadays, specifically with back office business progammers, it's pretty meaningless.
holy crap. That's me. I'd never thought of myself in quite those terms before. depressing..
Look forward to seeing your presentation on Thursday Mr P.
|
|
Message #216250
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
But ffs
The problem here is that there are two fairly different types of optimizations being talked about.
One is where you select algorithms based on data read/write patterns, such as picking the right sorting algorithm, doing things in the right order so that expensive operations don't get performed on data that obviously isn't going to need it for whatever reason. Another, also connect to this, is picking the right data structures based on data read/write-patterns and the size of N (how many items are we talking about) to make sure that the data actually fits in memory. This is real and ever so important and will never ever go away.
The other type of optimization, the type you numbnuts are talking about here is such a waste of time. As a newbie to optimization and programming you do not waste time trying to re-use this or that StringBuffer, worry about declaring ints in the wrong place and whatnot. I'd have fired almost every one of you numbnuts in this thread if you'd done any of tasks you mentioned. HotSpot needs/wants Regular and Proper Damn Java Code and so do you when a need arises to add more features/fix bugs. You should never type in things you think are smart and cool optimizataions because they're GOING to be wrong and make things go slower.
Dealing with code bases with millions of missused Strings and StringBuffers is making me go bald. And I can clearly see where the authors picked up whichever Cool Optimization some codpiece happens to represent. It's all from crap published on sites like this and/or JavaWorld and it's ALWAYS just a waste of his, mine and the CPU's time.
|
|
Message #216254
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Normally it doesn't matter
Normally you don't end up allocating new instances of objects inside a loop, you just iterate through them. Hence the performance penalty for declaring an Object reference is (about) the same as for declaring a native type.
|
|
Message #216272
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Re: But ffs
The other type of optimization, the type you numbnuts are talking about here is such a waste of time. As a newbie to optimization and programming you do not waste time trying to re-use this or that StringBuffer, worry about declaring ints in the wrong place and whatnot. I'd have fired almost every one of you numbnuts in this thread if you'd done any of tasks you mentioned.
Since most of the posts in this thread are saying basically what you have said here, why are you being such a hard-on?
|
|
Message #216307
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Actual results
Looks like the guy who wrote the article did a very thorough non-JIT analysis of code. But as near as I can tell, he didn't simply run the code and look at the results, and my take is that the "proof is in the pudding." This applies double when a JIT (e.g. HotSpot) compiler comes into play. Here are my results of the code from the article as run on Java 1.5.0_07 with 2,000,000,000 iterations on the primitives, and 100,000,000 iterations on the objects:
primitives test 1: 3344 milliseconds primitives test 2: 3390 milliseconds primitives test 3: 3125 milliseconds
objects test 1: 28828 milliseconds objects test 2: 24594 milliseconds objects test 3: 24421 milliseconds
The tests ran pretty consistently with times usually within a few hundred (or thousand for the objects) milliseonds of those shown, always with test 3 being the fastest.
Of course, there's a third variable to the overall equation not taken into considartion in the article (one beyond performance and readability, I mean): good coding practices. If we live by what we're told in Effective Java (by Josh Bloch), declaring the variable inside the loop is the best coding practice. This ties in to my own personal readability preferance for declaring it there. However, my personal preferences aside, with the results of test 3 combined with the recommendations from Effective Java, there should be enough influence, hopefully, to persuade any smart Java programmer to declare loop-local variables inside the loop.
|
|
Message #216349
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Re: Actual results
The tests ran pretty consistently with times usually within a few hundred (or thousand for the objects) milliseonds of those shown, always with test 3 being the fastest.
Yes, as Hotspot warms up, the code gets faster ;-)
You have to run in a loop, with each loop iteration running each of the tests in a random order, otherwise GC harmonics etc. will distort the results.
With the primitive test written taking these things into account, here are my results:
C:\java\[...]\jdk\142_04\bin\java -server -Xms128m -Xmx128m [...]
test 1: 0ms test 2: 121ms test 3: 0ms test 2: 20ms test 1: 0ms test 3: 0ms test 2: 0ms test 3: 0ms test 1: 0ms test 3: 0ms test 1: 0ms test 2: 0ms test 1: 0ms test 3: 0ms test 2: 0ms test 2: 0ms test 1: 0ms test 3: 0ms ...
... and so on. None of the tests took over 0ms once Hotspot kicked in. ;-)
For reference:
public static void main(String[] asArg) { for (int i = 0; i < 100; ++i) { testPrimitives(1000000000); } }
public static void testPrimitives(int count) { int nBase = getRandom().nextInt(3); boolean fFwd = getRandom().nextBoolean(); for (int i = 0; i < 3; ++i) { int nTest = (nBase + (fFwd ? i : -i) + 3) % 3; long lStart = System.currentTimeMillis(); switch (nTest) { case 0: testPrimitives1(count); break; case 1: testPrimitives2(count); break; case 2: testPrimitives3(count); break; default: azzert(); } long lStop = System.currentTimeMillis(); out("test " + (nTest + 1) + ": " + (lStop - lStart) + "ms"); } }
public static void testPrimitives1(int count) { int a = 0; for (int i = 0; i < count; i++) { a = i; } }
public static void testPrimitives2(int count) { int a; for (int i = 0; i < count; i++) { a = i; } }
public static void testPrimitives3(int count) { for (int i = 0; i < count; i++) { int a = i; } }
Peace,
Cameron Purdy Tangosol Coherence: The Java Data Grid
|
|
Message #216366
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Re: Java Performance vs. Readability
Different applications (Java or not) require different approaches. Readability is sometimes more important than performance, but not always.
The guys that have, and are deploying Cameron's product certainly care about performance (where milliseconds count).
They're also not just relying solely on products, VMs, compilers, etc. to achieve that performance.
|
|
Message #216393
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Java coding good practices ?
Hi all
I've read your topic with much interest. Indeed, to produce "good code" is something most of the developpers are, I think, eager to do.
However, having read all yours comments, I've the feeling that there's no "coding trick" but only "sound architecture/design solutions". Is this correct ? Is there nothing to avoid in order to have good performances ?
Furthermore, if you were to write some "Java coding good pratices", what would you say ?
IMHO, I just see : - use the right sort - limit the times you read/write files
What would you add ?
Thanks in advance ZedroS
|
|
Message #216421
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Re: Java coding good practices ?
Hi all
I've read your topic with much interest. Indeed, to produce "good code" is something most of the developpers are, I think, eager to do.
However, having read all yours comments, I've the feeling that there's no "coding trick" but only "sound architecture/design solutions". Is this correct ? Is there nothing to avoid in order to have good performances ?
There are but the general trend in programming languages is to elimate the need to use 'tricks' in code to improve preformance. The theory being that the code that best solves the real problem should be the code used and that the compiler or VM sohuld handle the details of making it fast.
Furthermore, if you were to write some "Java coding good pratices", what would you say ?
IMHO, I just see : - use the right sort - limit the times you read/write files
What would you add ?
Thanks in advance ZedroS
Using the correct data structure is important, probably more so than sorting because sorting of non-trivial length lists and arrays is a rarity in Java (from my experience) but use of structures like Lists and Maps is extremely common.
Since IO is on the order of 1000 times slower than in memory access, it's something to minimize.
The main point to take away from this is that if you do need to hand optimize something 1. make sure it's necessary 2. and make sure you know why you are doing it.
Often the first is not true. Maybe some piece of code is not optimal but it only happens once a day and executes in subsecond times. No need to mess with something like that. You are more likely to create issues than anything else.
The second is also a common failure. Many developers figure less lines of code is faster or bringing a variable declaration up out of a loop body will make things faster. But they haven't verified these assertions in any way. Make sure you know that your change will have a noticeable effect on performance.
|
|
Message #216573
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Re: Java coding good practices ?
Thanks for the answer.
Many developers figure less lines of code is faster or bringing a variable declaration up out of a loop body will make things faster. But they haven't verified these assertions in any way. Make sure you know that your change will have a noticeable effect on performance.
Do you think that bringing a variable out of a loop isn't improving performance ? Or rather that the improvement is small ? BTW, except running the code, do you have any other way to know what improves the code's performance ?
|
|
Message #218323
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Refering to James Watson's post
Well! with all respect,the topic has already been deprecated long back but I don't think it should stop somebody to raise it again(say for backward compatibility). The best outcome always comes from good design and efficient use of objects! Code readability matters when the code is evolving over time but performance is of most importance when you are fighting for milliseconds.
Primitives are always preferred over Wrappers and these has always been practised though we don't get much out of it but it surely doesn't mean we shouldn't.
The point always is: Encourage,Don't criticise.
|
|
Message #218335
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Re: Java coding good practices ?
Do you think that bringing a variable out of a loop isn't improving performance ? Or rather that the improvement is small ?
There is no improvement what so ever. The byte code is identical.
|
|
 |
New content on TheServerSide.comNew content on TheServerSide.comNew content on TheServerSide.com |
 |
 |
Reza Rahman explores the features of the proposed JSR 299, Contexts and Dependency Injection for Java EE (CDI). When approved, it promises to be a key feature of Java EE 6.
(November 2, Article)
SAML is an XML-based standard for exchanging authentication and authorization data between security domains. The single most important problem that SAML was created to solve is the Web browser Single Sign-On problem. Many organizations are debating whether to stay with version 1.1 or move to 2.0. This article makes observations about both options.
(September 28, Article)
Joe Ottinger takes a look at how people learn, and applies it to the practice of programming. He notes that understanding how people learn is an essential part of working in a programming team.
(September 22, Article)
Stephen Maryka gave us an article about the Asynchronous Web and posed a number of questions that get examined like an approach to delivering Asynchronous Web capabilities through extensions to existing Java EE technologies.
(July 14, Article)
JavaServer Faces Flex goal is to provide users capability in creating standard Flex components, part of flexSDK which is open sourced through MPL license, as normal JSF components. This article by Ji Hoon Kim will provide an overview of creating a simple multilingual JSF page consisting of JSF Flex tags.
(June 29, Article)
In this session Jeff explores the key characteristics of successful SOA projects. He covers some of the patterns, and anti-patterns, tool sets, and strategies that he himself learned the hard way. Last, he provides a strategy and blueprint for achieving a high likelihood of success in your SOA project.
(June 23, Tech Talk)
Ari Zilka, CTO of Terracotta, Inc., talks about the new features in Terracotta 3.1, announced during JavaOne and available now.
(June 15, Tech Talk)
In this Tech Talk, Josh Long explores an integration challenge using Spring Integration and walks through the implementation, employing and expanding on the basic patterns of Enterprise Application Integration to tie together components into a function integration solution, and then demonstrates how Spring Integration helps address the integration requirements.
(June 15, Tech Talk)
In this Tech Talk, David Geary teaches you: The basics of Google Web Toolkit; How to implement Ajax-enabled applications in Java; Internationalization; Hooking into the browser history mechanism; Remote procedure calls.
(June 4, Tech Talk)
Jon Kern discusses the best architecture/technical solutions and ensure that they are repeated by all developers. By tackling the architecture up-front in a serial manner, subsequent parallel development will be much more manageable and predictable.
(May 28, Tech Talk)
This keynote describes the frustrations of modern knowledge workers in their quest to actually get some work done, and solutions for how to guard yourself against all those distractions. Neal Ford talks about environments, coding, acceleration, automation, and avoiding repetition as ways to defeat the misguided attempts to sap your ability to produce good work.
(May 26, Tech Talk)
Gil demonstrates how new, aggressive uses of already abundant compute capacity by common applications offer competitive value for application designers.
(May 21, Tech Talk)
Chris Keene introduces WaveMaker as a new way to automate the ability to generate Hibernate classes in order to more quickly bring OR mapping into an application.
(May 19, Article)
In this session Nati Shalom demonstrates how to take a standard Java EE web application and scale it out or down dynamically without changes to the application code. Seeing as most web applications are over-provisioned to meet infrequent peak loads, this is a dramatic change because it enables growing your application as needed, when needed, without paying for unutilized resources.
(May 19, Tech Talk)
Download the entire book of Jakarta-Struts Live and learn about Struts MVC, Tiles, the Validator, DynaActionForms, plug-ins, internationalization, and more.
(Book PDF Download)
The Application Server Matrix is a detailed listing of J2EE vendors and their application server products, with information on latest version numbers, J2EE spec support and licensing, pricing, platform support, and links to product downloads and reviews.
(Application Server Comparison Matrix)
|
|