In Java, is there a performance hit if i continually use nested get to retrieve values? For instance:
String firstname = getOffice().getDepartment().getEmployee().getFirstName();
String lastname = getOffice().getDepartment().getEmployee().getLastName();
String address = getOffice().getDepartment().getEmployee().getAddress();
VS:
Employee e = getOffice().getDepartment().getEmployee();
String firstname = e.getFirstName();
String lastname = e.getLastName();
String address = e.getAddress();
Would the 2nd version be faster because it has less 'jumps'?
It depends entirely on what the getXYZ calls do. If they're simple accessors to an underlying field, then no, not on HotSpot (Oracle's JVM), because they'll get optimized out if there's any need to do so. If, on the other hand, they do any kind of complex work (traversing a btree, etc.), then of course they'll have to do that work repeatedly (unless HotSpot can prove to itself that the calls are idempotent, which if the code has any complexity becomes unlikely). (Whether it matters that they do the work repeatedly is another question; until/unless you see an actual performance problem, don't worry about it.)
But the second is much more readable and maintainable. That's the more powerful reason for using it.
Rather than performance I see second as better human understandable code. You should not worry about micro optimizations but write a good and clean code.
The optimization you are thinking about is called premature optimization. You should not think about these unless you really have to.
I agree with #AmitD's answer about being the second one more readable. When chaining method calls like this, you can also write them in the following way -
Employee e = getOffice()
.getDepartment()
.getEmployee();
String firstname = e.getFirstName();
String lastname = e.getLastName();
String address = e.getAddress();
to further improve readability.
Possibly yes. But assuming the getters look like ordinary getters on the inside it will probably be so small that it becomes almost impossible to measure.
Also if you run through this code often enough to make it matter, the magic of the Hotspot compiler will kick in and mangle the byte code, probably again making both variations the same.
In the end it is extremely hard to tell what really will happen. If performance matters for you set up a test. If performance doesn't matter enough to justify the costs of the test ... well then it doesn't matter enough to worry.
Either use byte code analysis or time the two approaches using System.nanoTime. I think second one is faster. here is what I did to conclude this:
I wrote three classes as given below:
public static class A {
public B b = new B();
}
public static class B {
public E e = new E();
}
public static class E {
public String name = "s";
public int age = 1;
}
Then I wrote two simple methods and get their java byte code using javap -c CLASS_NAME.
public static void Test1() {
A a = new A();
String str = a.b.e.name;
int age = a.b.e.age;
}
The byte code of above method is:
public static void Test1();
Code:
// new A();
0: new #15
3: dup
4: invokespecial #17
7: astore_0
8: aload_0
// a.b (it accesses the field and put it on operand stack)
9: getfield #18
// b.e
12: getfield #22
// b.name
15: getfield #28
// pop 'name' from stack
18: astore_1
19: aload_0
// cyle continues
20: getfield #18
23: getfield #22
26: getfield #34
29: istore_2
30: return
You can clearly see at byte code level, each time you try to access field, it put the value of that filed on stack and then this cycle continues. Therefore, a.a1.a2....an would be n instruction if stack would have enough spae to hold all n. And there was no optimisation by compiler this same cycle of called again to access both name and age field.
Now here is the second method:
public static void Test2() {
A a = new A();
E e = a.b.e;
String str = e.name;
int age = e.age;
}
Byte code for above method is:
public static void Test2();
Code:
// new A();
0: new #15
3: dup
4: invokespecial #17
7: astore_0
8: aload_0
// store a.b.e on operand stack once
9: getfield #18
12: getfield #22
15: astore_1
16: aload_1
// get 'name' field
17: getfield #28
20: astore_2
21: aload_1
// get 'age' field
22: getfield #34
25: istore_3
26: return
Above is 4 instruction shorter than previous code as it prevents execution of getfield. So I think this should be faster than previous one.
Related
Basically, you can have code like this:
From: Baeldung.com
public static synchronized ClassSingleton getInstance() {
if(instance == null) {
instance = new ClassSingleton();
}
return instance;
}
and you can have code like this:
My Version:
public static synchronized ClassSingleton getInstance() {
return instance = (instance == null) ? new ClassSingleton() : instance;
}
The code below is cleaner in any way, but SonarLints rule java:S1121 sees this as non-compliant (major, code smell)
So is there more behind this except the readability SonarLint is talking about?
I have a strange feeling that my version is doing always an assignment before returning, can this be a performance disbenefit?
Happy to hear what you guys have to say.
Yes it may have [probably negligible] performance implications. This can be tested by just trying to compile it and see what comes out. Here is the bytecode from Javac 16.0.1:
Compiled from "ClassSingleton.java"
public class ClassSingleton {
public ClassSingleton();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static synchronized ClassSingleton getInstance();
Code:
0: getstatic #7 // Field instance:LClassSingleton;
3: ifnonnull 16
6: new #8 // class ClassSingleton
9: dup
10: invokespecial #13 // Method "<init>":()V
13: putstatic #7 // Field instance:LClassSingleton;
16: getstatic #7 // Field instance:LClassSingleton;
19: areturn
public static synchronized ClassSingleton getInstanceShort();
Code:
0: getstatic #7 // Field instance:LClassSingleton;
3: ifnonnull 16
6: new #8 // class ClassSingleton
9: dup
10: invokespecial #13 // Method "<init>":()V
13: goto 19
16: getstatic #7 // Field instance:LClassSingleton;
19: dup
20: putstatic #7 // Field instance:LClassSingleton;
23: areturn
}
Via the age old metric of long=bad, the second version is clearly worse. In all seriousness though, it just performs 2 extra instructions in all cases. First dup duplicates the last item on the stack so it can then use that extra item to putstatic which assigns instance to the top value on the stack. We can speculate that if another thread is not synchronized on ClassSingleton, and instance has the correct attributes, then in theory we might get some weird behavior where instance might not be set correctly. However, that seems highly unlikely considering that synchronized handles most of that for us.
In the end though, the JIT compiler will probably remove the need for dup by using registers and it has a decent chance of figuring out tat it can get rid of that extra putstatic as well. However, I am not experienced enough with the JIT compiler to do more than speculate on how it might act.
That being said, just use the first version. It is way easier to read and generates shorter bytecode.
When we create a final in java it is guaranteed that it cannot be changed even at run time because the JVM guarantees it.
Java class:
public class JustATest {
public final int x = 10;
}
Javap decompiled:
Compiled from "JustATest.java"
public class JustATest {
public final int x;
public JustATest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: bipush 10
7: putfield #2 // Field x:I
10: return
}
But in scala, if we declare a val, it compiles into a normal integer and there is no difference between var and val in terms of decompilation output.
Original Scala class:
class AnTest {
val x = 1
var y = 2
}
Decompiled output:
Compiled from "AnTest.scala"
public class AnTest {
public int x();
Code:
0: aload_0
1: getfield #14 // Field x:I
4: ireturn
public int y();
Code:
0: aload_0
1: getfield #18 // Field y:I
4: ireturn
public void y_$eq(int);
Code:
0: aload_0
1: iload_1
2: putfield #18 // Field y:I
5: return
public AnTest();
Code:
0: aload_0
1: invokespecial #25 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_1
6: putfield #14 // Field x:I
9: aload_0
10: iconst_2
11: putfield #18 // Field y:I
14: return
}
With that information, the concept of immutability of a val is controlled only at compile time by the scala compiler? How is this guaranteed at run time?
In Scala, conveying immutability via val is a compile time enforcement which has nothing to do with the emitted byte code. In Java, you state that when the field is final in order for it not to be reassigned, where in Scala, declaring a variable with val only means it can't be reassigned, but it can be overridden. If you want a field to be final, you'll need to specify it as you do in Java:
class AnTest {
final val x = 10
}
Which yields:
public class testing.ReadingFile$AnTest$1 {
private final int x;
public final int x();
Code:
0: bipush 10
2: ireturn
public testing.ReadingFile$AnTest$1();
Code:
0: aload_0
1: invokespecial #19 // Method java/lang/Object."<init>":()V
4: return
}
Which is equivalent to the byte code you see in Java, except the compiler has emitted a getter for x.
The really simple answer is: there are some Scala features which can be encoded in JVM bytecode, and some which can't.
In particular, there are some constraints which cannot be encoded in JVM bytecode, e.g. sealed or private[this], or val. Which means that if you get your hands on the compiled JVM bytecode of a Scala source file, then you can do stuff that you can't do from Scala by interacting with the code through a language that is not Scala.
This is not specific to the JVM backend, you have similar, and even more pronounced problems with Scala.js, since the compilation target here (ECMAScript) offers even less ways of expressing constraints than JVM bytecode does.
But really, this is just a general problem: I can take a language as safe and pure as Haskell, compile it to native code, and if I get my hands on the compiled binary, all safety will be lost. In fact, most Haskell compilers perform (almost) complete type erasure, so there are literally no types, and no type constraints left after compilation.
With regard to Memory usage and variable instantiation which is better or is there no difference :
This
for(int i = 0; i < someValue; i++)
{
Obj foo = new Obj();
Use foo.....
}
As opposed to:
Obj foo;
for(int i = 0; i < someValue; i++)
{
foo = new Obj();
Use foo.....
}
There is no difference. Any potential difference in terms of memory usage would be optimized by the compiler.
If you compile (using javap -c) the two examples and compare the bytecode, you'll find that the bytecode is the same. Of course, this depends on the JVM version. But since this example is so trivial, it's probably safe to assume that neither is more memory efficient than the other.
Example 1:
Code:
public class example1 {
public static void main(String[] args) {
for (int i=0; i<10; i++) {
Object a = new Object();
}
}
}
Bytecode:
public class example1 extends java.lang.Object{
public example1();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: bipush 10
5: if_icmpge 22
8: new #2; //class java/lang/Object
11: dup
12: invokespecial #1; //Method java/lang/Object."<init>":()V
15: astore_2
16: iinc 1, 1
19: goto 2
22: return
}
Example 2:
Code:
public class example2 {
public static void main(String[] args) {
Object a;
for (int i=0; i<10; i++) {
a = new Object();
}
}
}
Bytecode:
public class example2 extends java.lang.Object{
public example2();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_2
2: iload_2
3: bipush 10
5: if_icmpge 22
8: new #2; //class java/lang/Object
11: dup
12: invokespecial #1; //Method java/lang/Object."<init>":()V
15: astore_1
16: iinc 2, 1
19: goto 2
22: return
}
With modern JVM both will work the same, also compiler optimization will take make both of them same.
Ignoring compiler optimization and modern JVM, 1st approach is better.
There is no difference between your examples, as is pointed out in other answers. But the interestiong question is: if your example is slow, what should you do?
If you want to reduce time spent in allocations/garbage collections in a really performance critical section, consider re-using objects instead of allocating new objects on each iteration.
foo = new Obj();
for(int i = 0; i < someValue; i++)
{
foo.init(i);
Use foo.....
}
From java performance tuning (an old book, but the same holds true in modern jvm:s and in the .NET clr)
... objects are expensive to create. Where
it is reasonable to reuse the same object, you should do so. You need
to be aware of when not to call new. One fairly obvious situation is
when you have already used an object and can discard it before you are
about to create another object of the same class. You should look at
the object and consider whether it is possible to reset the fields and
then reuse the object, rather than throw it away and create another.
This can be particularly important for objects that are constantly
used and discarded
The first example makes most sense in terms of object scope, but both should be as memory efficient as the other.
The compiler optimization will make both of them same. I prefer the first approach better, however, if you were to ignore the compiler optimization. It is more to the point and even Joshua Bloch suggests to do so in Effective Java (a great read).
The compiler should optimize this for you. I would prefer the first over the second as it is more readable. Letting Object foo have a larger scope could be a source of confusion.
One common dilemma I have faced throughout programming is regarding declaring variables inside a loop. Say I have to perform something like the following:
List list=myObject.getList();
Iterator itr=list.iterator();
while (itr.hasNext()){
BusinessObject myBo=(BusinessObject)itr.next();
process(myBo);
}
In the above snippet, should myBo be declared outside the loop or does declaring it inside the loop not cause harm to memory and performance?
Declaring it inside the loop won't cause any harm to the memory and performance.
If possible use List<BusinessObject> and Iterator<BusinessObject> to avoid casting:
List<BusinessObject> list = myObject.getList();
Iterator<BusinessObject> itr = list.iterator();
while (itr.hasNext()) {
process(itr.next());
}
One principle of good software design is to limit the scope of local variables, i.e. to declare them just in time within a block that ends soon after the last use of that variable. This doesn't affect performance or other "hard" aspects but makes the program more readable and easier to analyze.
In summary, doing what you're doing is considered GOOD.
myBo is simply a reference to an object (that is returned by itr.next()). As such the amount of memory that it needs is very small, and only created once, and adding it inside the loop should not affect your program. IMO, declaring it inside the loop where it is used actually helps make it more readable.
The most elegant solution for your loop would be an enhanced for loop (java 5 or newer):
List<BusinessObject> list = myObject.getList();
for( BusinessObject myBo : list ) {
process(myBo);
}
But even with the code you provided there will be no performance problem, because all the temporary variables only hold references to the BusinessObject, which is very cheap.
It doesn't cause any memory harm.
BTW unless you're omitting some code you may skip the declaration altogether:
while (itr.hasNext()){
//BusinessObject myBo=(BusinessObject)itr.next();
process((BusinessObject)itr.next());
}
If short -- no.
In C++ it could be a problem if myBo is created by copying
but in Java there is always used references, is'nt it?
for performance, its better to optimize something you are do in process()
Just have a look at the byte code with javap -c [ClassName]. Here's a class demonstrating a few examples of single-use variables with loops. The relevant bytecode dump is in the comments:
class HelloWorldLoopsAnnotated {
//
// HelloWorldLoopsAnnotated();
// Code:
// 0: aload_0
// 1: invokespecial #1; //Method java/lang/Object."<init>":()V
// 4: return
////////////////////////////////////////////////////////////////////////////
void stringDeclaredInsideLoop(){
while (true) {
// 0: ldc #2; //String Hello World!
String greeting = "Hello World!";
doNothing(greeting);
}
}
//
// void stringDeclaredInsideLoop();
// Code:
// 0: ldc #2; //String Hello World!
// 2: astore_1
// 3: aload_0
// 4: aload_1
// 5: invokespecial #3; //Method doNothing:(Ljava/lang/String;)V
// 8: goto 0
////////////////////////////////////////////////////////////////////////////
void stringDeclaredOutsideLoop(){
String greeting;
while (true) {
greeting = "Hello World!";
doNothing(greeting);
}
}
//
// void stringDeclaredOutsideLoop();
// Code:
// 0: ldc #2; //String Hello World!
// 2: astore_1
// 3: aload_0
// 4: aload_1
// 5: invokespecial #3; //Method doNothing:(Ljava/lang/String;)V
// 8: goto 0
////////////////////////////////////////////////////////////////////////////
void stringAsDirectArgument(){
while (true) {
doNothing("Hello World!");
}
}
// void stringAsDirectArgument();
// Code:
// 0: aload_0
// 1: ldc #2; //String Hello World!
// 3: invokespecial #3; //Method doNothing:(Ljava/lang/String;)V
// 6: goto 0
////////////////////////////////////////////////////////////////////////////
private void doNothing(String s) {
}
}
stringDeclaredInsideLoop() and stringDeclaredOutsideLoop() yield identical six-instruction bytecode. stringDeclaredInsideLoop() does still win: limited scope is best.
After some contemplation, I can't really see how tightening scope would ever affect performance: identical data in the stack would necessitate identical instructions.
stringAsDirectArgument(), however, defines the operation in only four instructions. Low memory environments (e.g. my magnificently dumb phone) may appreciate the optimization while a colleague reading your code may not, so exercise judgement before shaving bytes from your code.
See the full gist for more.
The temporary reference myBo is put on stack and should mostly be optimized away. There shouldn't be any performance penalty in your code.
maybe it's dumb but is there a difference between
new Something().method();
and
Something tmpSomething = new Something();
tmpSomething.method();
as I was calling only one method on this particular object, I chose the first solution but I'm not sure that this is exactly the same behavior...
I just want to mention the constructor initializes a Writer and method writes in this file...
I did a quick test. This is the extremely trivial test code:
public class TestLiveness
{
public static void test1()
{
System.out.println(new Square(4).square());
count();
}
public static void test2()
{
Square t = new Square(4);
System.out.println(t.square());
count();
}
private static void count()
{
for(int i=0; i<1000000; i++)
System.out.println(i);
}
static class Square
{
private int val;
Square(int val)
{
this.val = val;
}
int square()
{
return val * val;
}
}
}
Javap shows that the two methods are compiled differently; chaining doesn't touch the local variable table whereas the temporary variable does indeed stick around until the method returns. However, the VM/JIT compiler may still perform liveness analysis and allow the instance to be garbage collected before the method returns.
public static void test1();
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3; //class TestLiveness$Square
6: dup
7: iconst_4
8: invokespecial #4; //Method TestLiveness$Square."<init>":(I)V
11: invokevirtual #5; //Method TestLiveness$Square.square:()I
14: invokevirtual #6; //Method java/io/PrintStream.println:(I)V
17: invokestatic #7; //Method count:()V
20: return
public static void test2();
Code:
0: new #3; //class TestLiveness$Square
3: dup
4: iconst_4
5: invokespecial #4; //Method TestLiveness$Square."<init>":(I)V
8: astore_0
9: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
12: aload_0
13: invokevirtual #5; //Method TestLiveness$Square.square:()I
16: invokevirtual #6; //Method java/io/PrintStream.println:(I)V
19: invokestatic #7; //Method count:()V
22: return
There is no difference whatsoever except that in the second case you have an unnecessary variable lying around that makes the code harder to maintain.
Also, objects that get created only to be discarded after calling a single method constitute a code smell.
They are the same. Although constructing an object and only calling a single method on it may indicate poor design. Why not allow Something.method(); without needing to expose a constructor?
Well, in the second case you've got the object tmpSomething so you can use it throughout in the code but in the first example you don't. So you can't.
I imagine the first method is probably a touch more efficient but probably not the best practice for Java conventions.
If you can get some value from the first call maybe you might want to define your method static:
public static ____ method() {
}
There is a subtle difference between the two snippets, but only when viewed within their scope. Consider them within methods:
public void doSomething1() {
new Something().method();
doSomeLongRunningSomething();
}
public void doSomething2() {
Something tmpSomething = new Something();
tmpSomething.method();
doSomeLongRunningSomething();
}
In the first method, the 'something' is immediately available for garbage collection while in the second method, tmpSomething stays within scope during the run of doSomeLongRunningSomething. If you are doing anything interesting during the finalize (e.g. closing the file), this could introduce some quirks.
That said, my preference is for the second example and naming the new instance as it assists the debugging processing. While stepping through code you have a named instance that is easier to watch. That doesn't apply when you're getting pre-existing instances in which case I find chaining methods more readable, e.g. myDog.getEyes().getLeftEye().getColorAsRgb().getRed().
Firstly I'll agree with everyone else and say they are the same in terms of function.
However, I'm of the opposite opinion on what most are saying in this post, which is that I think the first example is the way to go.
And with the first example, I'd extend it even further with some form of dependency injection. This will get you in the habit of giving you the ability to test things if you need to inject a mock/test version of that 'Something' class.
Also by not train wrecking (doing more than one operation on the one line which is a code smell, e.g. new dog().getEyes().getColour();), in my opinion improves readability as well as optimises your ability to refactor later on. Just because at the moment you only call that one method on that object doesn't mean you won't need that object to do something else on it later meaning you will have to extract a variable for that 'Something' object anyway.
Nothing wrong with that, even when you call only one function.
Have a look at Fluent Interfaces on Wikipedia or Fluent Interfaces by Martin Fowler