Java performance versus code style: creating multiple method calls from a single line of code

I am curious if it is better to pack multiple and / or nested method calls within a single line of code, and that is why some developers do this because their code becomes less readable.

for instance

//like Set<String> jobParamKeySet = jobParams.keySet(); Iterator<String> jobParamItrtr = jobParamKeySet.iterator(); 

You can also write as

 //dislike Iterator<String> jobParamItrtr = jobParams.keySet().iterator(); 

Personally, I hate the latter because it performs several evaluations on one line and it is difficult for me to read the code. That is why I try to avoid to have more than one rating per line of code. I also do not know that jobParams.keySet() returns Set and this is me jobParams.keySet() .
Another example:

 //dislike Bar.processParameter(Foo.getParameter()); 

against

 //like Parameter param = Foo.getParameter(); Bar.processParameter(param); 

The first makes me poisonous and dizzy, because I like to consume simple and clean grades in every line of code, and I just hate it when I see that other people's code is written this way.

But are there any benefits (performance) to packing multiple method calls on the same line?

EDIT: Single liners are also harder to debug, thanks to @stemm for reminder

+6
source share
7 answers

Micro optimization is a killer. If the links to the code you are showing are the scope area of ​​the instance instance (or), I would go with the second approach.

Region region spectral variables will be eligible for GC as soon as the method is executed, so even you declare another variable, this is normal because the region is limited and the advantage you get will be readable and the code of the main table.

+6
source

I tend to disagree with most others on this list. I actually find the first way cleaner and easier to read.

In your example:

 //like Set<String> jobParamKeySet = jobParams.keySet(); Iterator<String> jobParamItrtr = jobParamKeySet.iterator(); Could be also written as //dislike Iterator<String> jobParamItrtr = jobParams.keySet().iterator(); 

the first method (the one you like) contains a lot of irrelevant information. For example, the whole point of an iterator interface is to give you a standard interface that you can use to loop through any supporting implementation. Thus, the fact that this is a key does not affect the code itself. All you need is an iterator to iterate over the implemented object.

Secondly, the second implementation actually gives you more information. It tells you that the code will ignore the implementation of jobParams and that it will only iterate over the keys. In the first code, you must first track that jobParamKeySet (as a variable) to find out what you are repeating. Also, you don't know if / where jobParamKeySet is used elsewhere in the area.

Finally, as a last comment, the second method makes it easy to switch implementations, if necessary; in the first case, you may need to transcode two lines (the first assignment to a variable if it changes from a set to something else), while in the second case you only need to change one line.

Thus, there are all limitations. A chain of 10 calls on the same line can be difficult to read and debug. However, 3 or 4 levels are usually clear. Sometimes, especially if an intermediate variable is required several times, it makes sense to declare it explicitly.

In your second example:

 //dislike Bar.processParameter(Foo.getParameter()); vs //like Parameter param = Foo.getParameter(); Bar.processParameter(param); 

Actually, it’s hard for me to understand which parameters are processed by Bar.processParameter(param) . It will take me more time to map param to the variable instance to see that it is Foo.getParameter() . In the first case, the information is very clear and very well presented - you process the parameters Foo.getParameter() . Personally, I think the first method is less error prone - it is unlikely that you accidentally use Foo2.getParamter() when it is within the same call, rather than a separate line.

+5
source

There is one lesser purpose of a variable, but even a compiler can optimize it in some cases. I would not do this for performance, it's a kind of early optimization . Write code that is easier to maintain.

In my case, I find:

 Iterator<String> jobParamItrtr = jobParams.keySet().iterator(); 

easier to read than:

 Set<String> jobParamKeySet = jobParams.keySet(); Iterator<String> jobParamItrtr = jobParamKeySet.iterator(); 

But I think this is a matter of personal taste.

+3
source

Code is never developed by the same user. I would choose the second way. It is also easier to understand and maintain.

It is also useful when two different teams work on code in different places.

Many times we take an hour or more to understand what another developer has done if he uses the first option. Personally, I have had this situation many times.

+1
source

But are there any benefits (performance) to packing multiple method calls on the same line?

I seriously doubt that the difference is measurable, but even if I thought that

I find it difficult to read the code.

to be much more important, it cannot be stated above.

Even if it were half the speed, I would still write the simplest, cleanest and easiest code to understand, and only when you profile the application and determine that you have a problem, I would think about optimizing it.

By the way: I prefer a denser, coded code, but I suggest you use what you prefer.

+1
source

The lack of an additional local variable probably has a negligible performance advantage (although JIT can optimize this).

Personally, I do not mind a chain of chains when it is pretty clear what has been done and the intermediate object is unlikely to be zero (for example, your first example is β€œnot like”). When it gets complicated (somewhat. In an expression), I prefer explicit local variables because it is much easier to debug.

Therefore, I decide in each case what I prefer :)

+1
source

I don't see where a().b().c().d much harder to read than abcd , which people don't seem to think too much about. (Although I will break it.) If you do not like that all this is on the same line, you can say

 a() .b() .c() .d 

(I don't like it either). I prefer to split it using a couple of extra variables. This makes debugging easier.

If performance is your concern (as it should be), the first thing to understand is not to sweat the little things. If adding extra local variables costs nothing at all, the rest of the code must be lifeless before it even matters.

0
source

Source: https://habr.com/ru/post/927265/


All Articles