• 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

Repeatedly Calling a Method to Return a Reference

 
Greenhorn
Posts: 24
Postgres Database VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Sheriff
Posts: 5555
326
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
How would that even be a valid optimization? It completely changes the semantics of the code.
 
Tim Cooke
Sheriff
Posts: 5555
326
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes it does. But this actually happens.
 
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Terry Tucker
Greenhorn
Posts: 24
Postgres Database VI Editor Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.

 
Terry Tucker
Greenhorn
Posts: 24
Postgres Database VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Paul Clapham
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
(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.
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Paul Clapham
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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".
 
Terry Tucker
Greenhorn
Posts: 24
Postgres Database VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 118
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.

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.
 
Whatever. Here's a tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic