Repeatedly Calling a Method to Return a Reference
posted 11 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
Greetings:
I have not posted here in a while.
I have a question related to performance. I have been working on some code that I did not write. In one section of the code, there were probably 50 calls to a public method in another class which simply returns a reference to an object. The same reference is returned over and over again with each call to the method. It is my style to declare a reference of that type at the beginning and use that reference from there on to the end. Now, here is the question: Is there any performance hit as a result of calling the method repeatedly as compared to declaring a single reference to the object and using it repeatedly?
Thanks in advance for any insight anyone can give.
I have not posted here in a while.
I have a question related to performance. I have been working on some code that I did not write. In one section of the code, there were probably 50 calls to a public method in another class which simply returns a reference to an object. The same reference is returned over and over again with each call to the method. It is my style to declare a reference of that type at the beginning and use that reference from there on to the end. Now, here is the question: Is there any performance hit as a result of calling the method repeatedly as compared to declaring a single reference to the object and using it repeatedly?
Thanks in advance for any insight anyone can give.
Terry Lee Tucker
Oracle Certified Associate
posted 11 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
My gut feeling says that you're worrying too much about something that's really not a big problem.
It's difficult to answer your question satisfactorily without seeing an example of what you mean though.
It's difficult to answer your question satisfactorily without seeing an example of what you mean though.
posted 11 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
The only way to know for sure is to run a performance test. Remember that the compiler will optimise code for you, and the JVM can also optimise.
However as already stated, it probably doesn't matter. Write code to be elegant and maintainable, and only if it doesn't perform well enough should you optimise it. And even then you should only optimise it once you have determined which bit is causing the problem.
However as already stated, it probably doesn't matter. Write code to be elegant and maintainable, and only if it doesn't perform well enough should you optimise it. And even then you should only optimise it once you have determined which bit is causing the problem.
posted 11 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
In extreme cases the compiler optimisation Mike mentions may bring about undesirable results. Say we have a loop in our code that is spinning waiting for some other value to change:
On the face of it this loop will spin until ref.getVal() returns something other than zero. But let's say ref.getVal() returns 0 tens of thousands of times in a row. The compiler optimisation will shortcut this loop to
At runtime the code is no longer looking at ref.getVal() at all so if it ever changes our code will not see it.
Granted the chances of this issue coming up in general development is very very low indeed. But it's an interesting consideration nonetheless should you be writing code that does this.
On the face of it this loop will spin until ref.getVal() returns something other than zero. But let's say ref.getVal() returns 0 tens of thousands of times in a row. The compiler optimisation will shortcut this loop to
At runtime the code is no longer looking at ref.getVal() at all so if it ever changes our code will not see it.
Granted the chances of this issue coming up in general development is very very low indeed. But it's an interesting consideration nonetheless should you be writing code that does this.
Tim Driven Development | Test until the fear goes away
Stephan van Hulst
Bartender
Posts: 15743
368
posted 11 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
How would that even be a valid optimization? It completely changes the semantics of the code.
posted 11 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
Yes it does. But this actually happens.
Tim Driven Development | Test until the fear goes away
posted 11 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
Yes, there's a performance hit. However it probably isn't as big as the performance hit which you would get by having a spot of mud on your sleeve while riding your bicycle -- that would contribute to wind resistance and therefore slow you down.
What I'm trying to say here is that you need a sense of proportion. When you're using a computer which can do several billion machine operations per second, a few hundred machine operations here and there aren't worth bothering about. What you should worry about are things which actually take significant amounts of time, like accessing hardware such as disks and network connections. The saying "Premature optimization is the root of all evil" dates back forty years but it's still as true as ever -- maybe more true because computers are much faster now than then.
What I'm trying to say here is that you need a sense of proportion. When you're using a computer which can do several billion machine operations per second, a few hundred machine operations here and there aren't worth bothering about. What you should worry about are things which actually take significant amounts of time, like accessing hardware such as disks and network connections. The saying "Premature optimization is the root of all evil" dates back forty years but it's still as true as ever -- maybe more true because computers are much faster now than then.
posted 11 years ago
-
1 -
-
Number of slices to send:Optional 'thank-you' note:
-
-
First, and foremost, thanks to all for the replies. I appreciate having a community of Java people who will answer questions regardless of the skill level of the person asking the question. I had forgotten how useful this forum is. That was to my detriment.
I have done some testing along these lines and I have found, given my best results, that there is a 40% increase in speed by setting a reference variable once with a getObject() as opposed to calling getObject() numerous times. My test could well be flawed; therefore, I am attaching the source code. At this point, I am convinced that it is far better to assign the reference once rather than to make multiple calls to the getObject() method. Also, in my opinion, it is easier to read and certainly makes for a shorter line of code. By the way, the test attached loops one million times in each test scenario. Further, the code that I am working on is a massive transportation system, one of the top two in the nation, which shall remain unnamed. This kind of thing is done thousands and thousands of times. I just wanted to add a little context to the conversation and the reason for my asking in the first place.
I would love to hear your comments. Further, let me state again, that I appreciate the various responses to my questions. The value of that cannot be under estimated.
I have done some testing along these lines and I have found, given my best results, that there is a 40% increase in speed by setting a reference variable once with a getObject() as opposed to calling getObject() numerous times. My test could well be flawed; therefore, I am attaching the source code. At this point, I am convinced that it is far better to assign the reference once rather than to make multiple calls to the getObject() method. Also, in my opinion, it is easier to read and certainly makes for a shorter line of code. By the way, the test attached loops one million times in each test scenario. Further, the code that I am working on is a massive transportation system, one of the top two in the nation, which shall remain unnamed. This kind of thing is done thousands and thousands of times. I just wanted to add a little context to the conversation and the reason for my asking in the first place.
I would love to hear your comments. Further, let me state again, that I appreciate the various responses to my questions. The value of that cannot be under estimated.
Terry Lee Tucker
Oracle Certified Associate
posted 11 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
I can see that my code did not format properly at all. I did click "Code" and the pasted the code after that; however, I am obviously doing something wrong in this process.
Terry Lee Tucker
Oracle Certified Associate
posted 11 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
(You're supposed to paste the code between the pair of tags the "Code" button makes, not after them. I fixed that for you.)
Most micro-benchmarks are flawed in some way; it's very hard to do those things right because you've got a JVM which will optimize things behind the scenes and even a CPU which will optimize things in unexpected ways. So I'd suggest doing the same thing, only doing test2() before test1().
The other thing to point out is that you aren't testing real code. In the real application you're going to be getting a reference (either by already having it or by calling a trivial method) and then doing something with that reference. So it might take 2.8 microseconds instead of 2 microseconds to call the trivial method, but if that's followed by code which takes 400 microseconds to run, then it isn't worth worrying about. Frankly I wouldn't change any existing code based on this benchmark unless I had some performance data which suggested there was a problem and this issue was it.
Most micro-benchmarks are flawed in some way; it's very hard to do those things right because you've got a JVM which will optimize things behind the scenes and even a CPU which will optimize things in unexpected ways. So I'd suggest doing the same thing, only doing test2() before test1().
The other thing to point out is that you aren't testing real code. In the real application you're going to be getting a reference (either by already having it or by calling a trivial method) and then doing something with that reference. So it might take 2.8 microseconds instead of 2 microseconds to call the trivial method, but if that's followed by code which takes 400 microseconds to run, then it isn't worth worrying about. Frankly I wouldn't change any existing code based on this benchmark unless I had some performance data which suggested there was a problem and this issue was it.
Mike. J. Thompson
Bartender
Posts: 689
17
posted 11 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
I'm with Paul on this. Assuming for a second that your benchmark is meaningful and its 40% faster to store the reference (which is a big assumption). You may well have just gained 40% improvement in code that only accounts for 0.1% of the running time of the particular feature in question.
So the things you need to ask yourself are:
* What are the performance requirements of the system?
* Does it currently meet those requirements? If it does then there's no need to worry about this.
* If it doesn't meet the requirements then what are the bottlenecks? You need to run the system in a profiler and actually see where the performance problem is. Any optimisation before then is just stabbing in the dark. The more complex your system is, the more true my last statement becomes.
All of that being said, I notice that you think extracting the method call improves the look of the code. That is a good reason to make the change. Unless you have evidence of a performance problem then your main aim should be to write readable, maintainable code.
So the things you need to ask yourself are:
* What are the performance requirements of the system?
* Does it currently meet those requirements? If it does then there's no need to worry about this.
* If it doesn't meet the requirements then what are the bottlenecks? You need to run the system in a profiler and actually see where the performance problem is. Any optimisation before then is just stabbing in the dark. The more complex your system is, the more true my last statement becomes.
All of that being said, I notice that you think extracting the method call improves the look of the code. That is a good reason to make the change. Unless you have evidence of a performance problem then your main aim should be to write readable, maintainable code.
posted 11 years ago
-
1 -
-
Number of slices to send:Optional 'thank-you' note:
-
-
Like what Mike said, I do agree that if reducing the number of method calls makes the program simpler to understand then I would definitely do that too. But even so I wouldn't do it if there were more critical things to do, like fix things which didn't work right and add new features. There's an old rule sometimes called "Ann Landers' Law" (not sure why) which says "If it ain't broke, don't fix it".
posted 11 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
Gentlemen,
Thanks to Mike, Paul, Tim, and Stephan for all the comments.
The reason for the question in the first place is more of a question about coding style than anything else. To go and change existing code solely for the purpose of getting rid of the multiple method calls would be ridiculous at best. As a coding style however, I intend to do it the way I have communicated because I think that is a "better way" for a number of reasons.
Again, thank you for the good advice and counsel.
Thanks to Mike, Paul, Tim, and Stephan for all the comments.
The reason for the question in the first place is more of a question about coding style than anything else. To go and change existing code solely for the purpose of getting rid of the multiple method calls would be ridiculous at best. As a coding style however, I intend to do it the way I have communicated because I think that is a "better way" for a number of reasons.
Again, thank you for the good advice and counsel.
Terry Lee Tucker
Oracle Certified Associate
posted 11 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
I know you've already gotten several answers and seem done with the conversation but after looking at this a couple of comments occurred to me.
As you've already found out, yes. Any code that isn't necessary for a correct result will at best be optimized out by your compiler and at worst will slow down your application.
At least one other person has already correctly pointed out that it's rarely necessary or beneficial to try to identify and eliminate performance problems in advance, but I can still think of a couple of reasons to remove the offending code in this specific case. For one thing, the extra method call would make debugging marginally more complex and time-consuming. More importantly, though, the method call is entirely unnecessary: what you have is an object with an instance method that returns a reference to . . . itself. In other words, the method is nonsensical because by definition the fact that you're able to call it means that you already have the information it will return. As someone already pointed out a good, clean design is preferable to one that seems to provide better performance, but in this case it's not a trade-off: the cleaner design will also yield better performance.
I say all this, of course, without any context beyond what you've provided. The answer might be different if, for example, GetObject is extended and its getObject() method overridden, but based on what you've shown here the method call is essentially what we used to call a "no-op": it does nothing but take up space and should be removed.
Terry Tucker wrote:Is there any performance hit as a result of calling the method repeatedly as compared to declaring a single reference to the object and using it repeatedly?
As you've already found out, yes. Any code that isn't necessary for a correct result will at best be optimized out by your compiler and at worst will slow down your application.
At least one other person has already correctly pointed out that it's rarely necessary or beneficial to try to identify and eliminate performance problems in advance, but I can still think of a couple of reasons to remove the offending code in this specific case. For one thing, the extra method call would make debugging marginally more complex and time-consuming. More importantly, though, the method call is entirely unnecessary: what you have is an object with an instance method that returns a reference to . . . itself. In other words, the method is nonsensical because by definition the fact that you're able to call it means that you already have the information it will return. As someone already pointed out a good, clean design is preferable to one that seems to provide better performance, but in this case it's not a trade-off: the cleaner design will also yield better performance.
I say all this, of course, without any context beyond what you've provided. The answer might be different if, for example, GetObject is extended and its getObject() method overridden, but based on what you've shown here the method call is essentially what we used to call a "no-op": it does nothing but take up space and should be removed.
| Get me the mayor's office! I need to tell him about this tiny ad: Paul Wheaton's 16th Kickstarter: Gardening playing cards for gardeners and homesteaders https://coderanch.com/t/889615/Paul-Wheaton-Kickstarter-Gardening-playing |











