Performance & method calls

Hi,

Is there any (noticable) difference between A and B?

public LargeObject a()

{

return b();

}

public LargeObject b()

{

return c();

}

public LargeObject c()

{

return d();

}

public LargeObject d()

{

returnnew LargeObject();

}

A.

....

LargeObject lo=d();

....

B.

....

LargeObject lo=a();

....

I believe that since only the reference is passing from method to method and there is only one instance of LargeObject the cost is not raised (a lot). Is that true?

I would like also to ask if the is any performance difference between:

a. MyClass.getField().doSomething();

b. MyClass.field.doSomething();

in case field is accesible in both ways.

Thanx in advance

[1411 byte] By [mathuoa] at [2007-9-30 7:07:00]
# 1

> I believe that since only the reference is passing

> from method to method and there is only one instance

> of LargeObject the cost is not raised (a lot). Is that

> true?

From the memory perspective, that is true. Only one LargeObject is allocated.

From the speed perspective, that is also true. I created a test program that basically called a() or d() 1000 times, and the speed was about the same (sometimes even exactly the same).

Of course, it would be better just to call d() -- a smaller method call stack is always better. Makes life easier for the JVM =)

> I would like also to ask if the is any performance

> difference between:

> a. MyClass.getField().doSomething();

> b. MyClass.field.doSomething();

From a OO-design perspective, option a. is better.

From a performance perspective, I created another test program calling an arbitrary method 10 million times using both ways, and there was no visible speed difference.

If there was a difference, this difference would be smaller than that of the problem stated above. In the above problem, four methods are put on the call stack. In this problem, getField() is put on the call stack but immediate resolves to some value, which is used to doSomething(). Therefore, the call stack for the second problem is, at any time, at most 1 method.

Hope this helps and makes sense,

- D.t.O

DrinkHotJavaCoffee at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 2
Thanx a lot for the reply, the informations provided are very helpful. I am in a designing stage and those questions were crucial.
mathuoa at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 3

> the informations provided are very helpful. I am in a

> designing stage and those questions were crucial.

you are maybe designing at the wrong level? normally cpu-time is chewed up by what the program is doing, rather than how the programming language is implemented itself. Put another way, the efficiency of java language constructs is not something you should worry about at design time.

asjf at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 4

> the informations provided are very helpful. I am in a

> designing stage and those questions were crucial.

I'm glad that I was able to help.

Regarding the question of whether to use object.field or object.getField() -- usually, it is best to have get & set methods for all fields. For example, if you want the user to input a ZIP code, and you simply say user.zip = zipCode;

there is room for errors if the user enters, for example, a 10-digit ZIP. Thus, every time you set the ZIP code in this hypothetical example, you need to do error checking. It would be better just to make the variable zip private and provide get & set methods: private long zip;

public void setZIP(long zipCode) {

// do error checking here

...

// if no errors, set the zip

zip = zipCode;

}

public long getZIP() {

return zip;

}

Because zip, in this second example, is be a private variable, you would not need to worry about the validity of the ZIP code. Every time zip is set, it is checked for errors.

This approach is better because the variable (zip) cannot be accessed from outside the class, guaranteeing that it contains a valid value. Moreover, performance is not significantly affected.

Good Luck with your program,

- D.t.O

DrinkHotJavaCoffee at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 5

Things that chew up performance

- Forgetting to disable your debug statements in production code

Usually you try to squeeze microseconds from your code and forget to disable debug statements as the following:

log.debug ("passed here" + step);

You need to use

if (log.isDebugEnabled()) {

log.debug ("passed here" + step);

}

where "isDebugEnabled()" checks a boolean flag indicating if your class is in debug mode or in production mode (it is a configuration option in log4j.properties). The costful string concatenation and string conversion are avoided.

- Using direct connections to databases instead of pooled connections

Pooled connections are real time savers and are available in every J2EE application server. Use the pooled connections.

- Using the wrong algorithms

Sort your data using bubblesort instead of using the canned algorithms in Java and you will suffer the consequences of using the wrong algorithm for your job.

etc.

edsonw at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 6

I completely agree with edsonw.

Also, if you don't care too much about accuracy, you can create your own scheme of decimals. doubles and floats are very slow due to the IEEE specification. =(

If you'd like me to go into more detail, ask. I don't want to write the details unless you want them.

Regards,

- D.t.O

DrinkHotJavaCoffee at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 7
I think your question falls into the category of "premature optimisation". Passing a reference up 3 stack frames is always going to be insignificant compared to allocating memory for a new object, big or small.
ARae at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 8

>you are maybe designing at the wrong level? normally cpu-time is chewed up by what the program is

>doing, rather than how the programming language is implemented itself. Put another way, the efficiency

>of java language constructs is not something you should worry about at design time.

Well, i am not wondering if Java is well constructed (actually i don't care since i can't do nothing about it).

In fact, my concern is to adapt my algorithms and programming style to what best suits to Java.

private long zip;

public void setZIP(long zipCode)

{

// do error checking here...

// if no errors, set the zip

zip = zipCode;

}

public long getZIP()

{

return zip;

}

This is nice, but some validity checks may cost a lot. In that case such a setter called 1000 times in one call of an operation would slow down the whole program without any reason, since this setter is useful only when errorneous data may be given. In my oppinion, another setter "requiring valid data" (without checks) is useful for "internal" calls when you know that the data given are produced through a proccess which gives valid results. Maybe this is stupid, but the application, which currently have some performance problems, deals with polynomials and each "set" needs a thousand validity checks. But through the proccess all polynomials are valid and there is no need for checks.

So, i believe there is a dinstiction to be made between "right style" and "adequate style" (i am not sure if adequate is the word). And concerning performance, you have to sacrify a lot in order to avoid errors, but when errors are excluded from the proccess you can hope to something better in performance.

> Things that chew up performance

> - Forgetting to disable your debug statements in production code

> - Using direct connections to databases instead of pooled connections

> - Using the wrong algorithms

This is a very useful (but sort i believe) list of tips. Thanx

In my case nor db are involved neither debug statements.

Concerning wrong algorithms...

Ok, the one i used is not the best (but should work).

>Also, if you don't care too much about accuracy, you can create your own scheme of decimals. doubles >and floats are very slow due to the IEEE specification. =(

>If you'd like me to go into more detail, ask. I don't want to write the details unless you want them.

This is very useful to know. Actually i am using BigInteger and BigDecimal.

(pls if this is wrong don't say "What an a*****e, he asks for slight differences, when he uses this", my question is mainly for reasons of "How to write code, that deals with MANY calls and consumes a lot of memory" )

Anyway, thank all of you for the help. I learnt a lot of very useful things.

Thanx again.

P.S. To whom my concern the application is about polynomials and ideals, and the "challenging" method is the implementation of Buchberger algorithm for Groebner Bases.

mathuoa at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 9

> This is nice, but some validity checks may cost a lot.

> In that case such a setter called 1000 times in one

> call of an operation would slow down the whole program

> without any reason, since this setter is useful only

> when errorneous data may be given.

I still think you might be missing the point here :)

Its a different mindset from C or C++, so if you are coming from that background then you should maybe put effort into avoiding borrowing idioms from those languages

For example, the efficiency of getting and setting most probably will have *no impact* on the speed of your code for two reasons

1) It probably won't be a bottleneck so even if its 10 times slower it will add at most a couple of milliseconds to your program

2) If it is in a bottleneck, then i believe the hotspot compiler will notice and do some magic inlining behind the scenes

It really is best to put encapsulation and clean design before optimisation - optimisation at the level you're talking about is not something typically done as part of normal java coding - its something you do once you've finished coding and everything works. You can get hold of a profiler (eg HP JMeter) and profile you're application to see where the bottlenecks are and then examine how to optimise them (which usually involves caching of some slow resource)

> So, i believe there is a dinstiction to be made

> between "right style" and "adequate style" (i am not

> sure if adequate is the word). And concerning

> performance, you have to sacrify a lot in order to

> avoid errors, but when errors are excluded from the

> proccess you can hope to something better in

> performance.

I see what you are saying here - that there is a balance to be made - I suppose a lot of examples in text books that wrap some small functionality in gold-plated armour to demonstrate encapsulation are guilty of going too far. Examples where encapsulation is bypassed are things like java.awt.Rectangle?

asjf at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 10

> This is nice, but some validity checks may cost a lot.

> In that case such a setter called 1000 times in one call of an operation would slow down the whole program

> without any reason, since this setter is useful only when errorneous data may be given. In my oppinion,

> another setter "requiring valid data" (without checks) is useful for "internal" calls when you know that the

> data given are produced through a proccess which gives valid results. Maybe this is stupid, but the

> application, which currently have some performance problems, deals with polynomials and each "set" needs

> a thousand validity checks. But through the proccess all polynomials are valid and there is no need for

> checks.

You might want to think about choosing a different encapsulation boundary, so that your process and data are in the same object. Then the checks are only applied when the data source is external to that object, not as part of the internal processes.

Pete

PeteKirkham at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 11

> You might want to think about choosing a different

> encapsulation boundary, so that your process and data

> are in the same object. Then the checks are only

> applied when the data source is external to that

> object, not as part of the internal processes.

i'd still say only do this if it makes sense from the object model point of view - not just for performance (unless you really have determined that this is a bottleneck)

asjf at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 12

> So, i believe there is a dinstiction to be made

> between "right style" and "adequate style" (i am not

> sure if adequate is the word). And concerning

> performance, you have to sacrify a lot in order to

> avoid errors, but when errors are excluded from the

> proccess you can hope to something better in

> performance.

I think everyone here is agreeing with you but trying to explain that method calls are not, by themselves, going to cause significant impact. IIRC, some basic testing on average computers done as a result of other threads found that method calls by themselves were almost undetectable in computer time. A 1000 calls might add up to a microsecond of processing time.

Using proper data structures and avoiding lots of unnecessary Object creations will be a lot more effective.

dubwai at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 13
In the end, it's the algorithm itself and the amount and number of times memory is allocated that really counts.Also, if everything is guaranteed to be valid, go ahead and use a public field for getting & setting.Good Luck, - D.t.O
DrinkHotJavaCoffee at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...
# 14

> Also, if everything is guaranteed to be valid, go

> ahead and use a public field for getting & setting.

A package protected variable might be an option in certain cases. However, using properties instead of methods can be extremely limiting and become a maintenance nightmare.

For example, lets say you use a public variable. You write a bunch of code that accesses it. Then later you determine synchronization is needed. You (or someone else) will have to find every use of the variable and synchronize around it. While feasible, such changes are error-prone and time consuming. There are innumerable other senarios where methods will help in changes that happen later. It's almost always worth the cost of the method call to avoid such issues.

dubwai at 2007-7-1 23:13:47 > top of Java-index,Other Topics,Algorithms...