This question already has answers here:
Calling getters on an object vs. storing it as a local variable (memory footprint, performance)
(6 answers)
Closed 5 years ago.
To check a string input before using it, I often use code as shown in the first block. The second block does the same, but is there a difference in performance? (for example, is the textfield read twice in the first code block?) Also is one considered as bad coding or can I use both of them?
if (!textField.getText().equals("")) {
name = textField.getText();
}
or
String ipt = textField.getText();
if (!ipt.equals("")) {
name = ipt;
In terms of performance, the second is faster as it spares a duplicated processing.
But it is a so cheap task that you should execute it million times to see a difference.
Besides, modern JVMs performs many optimizations. Which could result in similar performance in both cases.
But in these two ways, I notice bad smells :
This way :
if (!textField.getText().equals("")) {
name = textField.getText();
}
introduces duplication.
It is generally unadvised as if we forget to change the duplicate everywhere we may introduce issues.
Duplicating one line of code is often not a serious issue but generally textfields are not single. So you perform very probably this task for multiple textfields. Duplication becomes so a problem.
This way :
String ipt = textField.getText();
if (!ipt.equals("")) {
name = ipt;
introduces a local variable that has a scope broader than required. It is also discouraged to make the code less error prone as we may reuse the variable after the processing where it is required while we should not be able to.
For your requirement, I dislike both solutions.
A better quality and efficient way would be introduce a method :
private String getValueOrDefault(TextField textField, String defaultValue) {
String value = textField.getText();
return !value.equals("") ? value : defaultValue;
}
You can invoke it in this way :
name = getValueOrDefault(textField, name);
You don't have any longer a variable that lives beyond its requirement and you don't have duplication either.
The second one is likely faster. That is because the first one calls getText() twice. The second one only stores it once, then can be accessed. However, since it is defined in a variable, it might be the same. This is likely the fastest way to do it:
if (!(String value=textField.getText().equals(""))
name = value;
EDIT: As said by someone in the comments, the above is NOT faster. Sorry for the answer, I didn't run it through a timer.
Related
Let's say I do something like this in Java 8 (Android specifically)
String name = someObject.getName() != null ? someObject.getName() : "null";
and the method getName() might have a lot of calls to other methods to resolve the name. Also suppose I'm calling this code quite often.
Would it be better, performance wise, to do something like this instead?
String name = someObject.getName();
name = name != null ? name : "null";
This looks like an optimization possible, called CSE; a JVM AFAIK does that (but not sure about Android).
But this highly depends on what getName does, if it allocates internally other objects and does some other things. Unfortunately I can't even tell how to prove me wrong or right here (might need to investigate); honestly I have a habit of doing this myself. For example:
for(int i=0;i<list.size();++i){
}
I try to always extract the int size = list.size() before the loop; even if this in my understanding is subject to scalar replacement optimization.
The second version is calling getName one time, while the first, in case is not null, it's calling that 2 times... so if it is very heavy, the second version is better.
As Arnaud said, you have to consider if the value can change between the two calls: in this case you will get a performance boost, but a risk to get an "old" value.
If I have a string that is currently empty
String s = "";
and reassign it
s = "";
is it bad it I don't do it like this?
if(!s.isEmpty()){
s = "";
}
or will the compiler pick up on it and optimize for me?
the cost of calling the method isEmpty() (allocating new space in the thread stack etc) negate any gains. if you want to assign an empty String to the variable, its most efiicient to do so without the if statement.
Do not micro-pessimize your code.
s = "";
The assignment gets translated by JIT into a move into register, where the source most probably resides in register as well (in a loop, such an optimization gets done unless you run out of registers). So it's the fastest instruction taking just one cycle and current Intel can execute 4 of them in parallel.
if(!s.isEmpty()){
s = "";
}
The function call is not a problem, as it gets inlined. But there's still a memory indirection from the String to it's value.length. Not bad, but already way more expensive than the simple way. Then a conditional branch, which can take tens of cycles, unless the outcome can be predicted by the CPU. If not, you still may be lucky and the JIT may replace it by a conditional move. Whatever happens, it can never be faster than the simpler code.
Addendum
In theory, you could hope that the JIT finds out that the two variants are equivalent and replaces the pessimized one by the simple one. But these two variants are not equivalent. You'd need to use
if (s != "") {
s = "";
}
instead as there may be other empty string than the interned one (i.e., the compile time constant ""). Anyway, I hope that we agree that the above snippet is something nobody should ever use.
If there's any real logic between the initialization and the point at which you assign "" again, the compiler probably won't be able to optimize it out. But it's fine if it doesn't, because the reassignment isn't going to take any significant time. In theory, if it did, the Just-In-Time compiler (JIT) in the JVM (well, Oracle's JVM, anyway) would try to optimize it (if it could) if it ended up being a "hot spot" in the code.
In the following piece of code we make a call listType.getDescription() twice:
for (ListType listType: this.listTypeManager.getSelectableListTypes())
{
if (listType.getDescription() != null)
{
children.add(new SelectItem( listType.getId() , listType.getDescription()));
}
}
I would tend to refactor the code to use a single variable:
for (ListType listType: this.listTypeManager.getSelectableListTypes())
{
String description = listType.getDescription();
if (description != null)
{
children.add(new SelectItem(listType.getId() ,description));
}
}
My understanding is the JVM is somehow optimized for the original code and especially nesting calls like children.add(new SelectItem(listType.getId(), listType.getDescription()));.
Comparing the two options, which one is the preferred method and why? That is in terms of memory footprint, performance, readability/ease, and others that don't come to my mind right now.
When does the latter code snippet become more advantageous over the former, that is, is there any (approximate) number of listType.getDescription() calls when using a temp local variable becomes more desirable, as listType.getDescription() always requires some stack operations to store the this object?
I'd nearly always prefer the local variable solution.
Memory footprint
A single local variable costs 4 or 8 bytes. It's a reference and there's no recursion, so let's ignore it.
Performance
If this is a simple getter, the JVM can memoize it itself, so there's no difference. If it's a expensive call which can't be optimized, memoizing manually makes it faster.
Readability
Follow the DRY principle. In your case it hardly matters as the local variable name is character-wise as about as long as the method call, but for anything more complicated, it's readability as you don't have to find the 10 differences between the two expressions. If you know they're the same, so make it clear using the local variable.
Correctness
Imagine your SelectItem does not accept nulls and your program is multithreaded. The value of listType.getDescription() can change in the meantime and you're toasted.
Debugging
Having a local variable containing an interesting value is an advantage.
The only thing to win by omitting the local variable is saving one line. So I'd do it only in cases when it really doesn't matter:
very short expression
no possible concurrent modification
simple private final getter
I think the way number two is definitely better because it improves readability and maintainability of your code which is the most important thing here. This kind of micro-optimization won't really help you in anything unless you writing an application where every millisecond is important.
I'm not sure either is preferred. What I would prefer is clearly readable code over performant code, especially when that performance gain is negligible. In this case I suspect there's next to no noticeable difference (especially given the JVM's optimisations and code-rewriting capabilities)
In the context of imperative languages, the value returned by a function call cannot be memoized (See http://en.m.wikipedia.org/wiki/Memoization) because there is no guarantee that the function has no side effect. Accordingly, your strategy does indeed avoid a function call at the expense of allocating a temporary variable to store a reference to the value returned by the function call.
In addition to being slightly more efficient (which does not really matter unless the function is called many times in a loop), I would opt for your style due to better code readability.
I agree on everything. About the readability I'd like to add something:
I see lots of programmers doing things like:
if (item.getFirst().getSecond().getThird().getForth() == 1 ||
item.getFirst().getSecond().getThird().getForth() == 2 ||
item.getFirst().getSecond().getThird().getForth() == 3)
Or even worse:
item.getFirst().getSecond().getThird().setForth(item2.getFirst().getSecond().getThird().getForth())
If you are calling the same chain of 10 getters several times, please, use an intermediate variable. It's just much easier to read and debug
I would agree with the local variable approach for readability only if the local variable's name is self-documenting. Calling it "description" wouldn't be enough (which description?). Calling it "selectableListTypeDescription" would make it clear. I would throw in that the incremented variable in the for loop should be named "selectableListType" (especially if the "listTypeManager" has accessors for other ListTypes).
The other reason would be if there's no guarantee this is single-threaded or your list is immutable.
Class A
Class A {
public HashMap <Integer,Double> myHashMap;
public A(){
myHashMap = new HashMap()
}
}
class B
Class B {
private A anInstanceOfA;
public B(A a) {
this.anInstanceOfA = a;
}
aMethod(){
anInstanceOfA.myHashMap.get(1); <--getting hashmap value for key = 1
//proceed to use this value, but instead of storing it to a variable
// I use anInstanceOfA.myHashMap.get(1) each time I need that value.
}
In aMethod() I use anInstanceOfA.myHashMap.get(1) to get the value for key = 1. I do that multiple times in aMethod() and I'm wondering if there is any difference in efficiency between using anInstanceOfA.myHashMap.get(1) multiple times or just assigning it to a variable and using the assigned variable multiple times.
I.E
aMethod(){
theValue = anInstanceOfA.myHashMap.get(1);
//proceed to use theValue in my calculations. Is there a difference in efficiency?
}
In theory the JVM can optimise away the difference to be very small (compared to what the rest of the program is doing). However I prefer to make it a local variable as I believe it makes the code clearer (as I can give it a meaningful name)
I suggest you do what you believe is simpler and clearer, unless you have measured a performance difference.
The question seems to be that you want to know if it is more expensive to call get(l) multiple times instead of just once.
The answer to this is yes. The question is if it is enough to matter. The definitive answer is to ask the JVM by profiling. You can, however, guess by looking at the get method in your chosen implementation and consider if you want to do all that work every time.
Note, that there is another reason that you might want to put the value in a variable, namely that you can give it a telling name, making your program easier to maintain in the future.
This seems like a micro-optimization, that really doesn't make much difference in the scheme of things.
As #peter already suggested, 'optimizing' for style/readability is a better rationale for choosing the second option over the first one. Optimizing for speed only starts making sense if you really do a lot of calls, or if the call is very expensive -- both are probably not the case in your current example.
Put it in a local variable, for multiple reasons:
It will be much faster. Reading a local variable is definitely cheaper than a HashMap lookup, probably by a factor of 10-100x.
You can give the local variable a good, meaningful name
Your code will probably be shorter / simpler overall, particularly if you use the local variable many times.
You may get bugs during future maintenance if someone modifies one of the get calls but forgets to change the others. This is a problem whenever you are duplicating code. Using a local variable minimises this risk.
In concurrent situations, the value could theoretically change if the HashMap is modified by some other code. You normally want to get the value once and work with the same value. Although if you are running into problems of this nature you should probably be looking at other solutions first (locking, concurrent collections etc.)
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I understand that every time I type the string literal "", the same String object is referenced in the string pool.
But why doesn't the String API include a public static final String Empty = "";, so I could use references to String.Empty?
It would save on compile time, at the very least, since the compiler would know to reference the existing String, and not have to check if it had already been created for reuse, right? And personally I think a proliferation of string literals, especially tiny ones, in many cases is a "code smell".
So was there a Grand Design Reason behind no String.Empty, or did the language creators simply not share my views?
String.EMPTY is 12 characters, and "" is two, and they would both be referencing exactly the same instance in memory at runtime. I'm not entirely sure why String.EMPTY would save on compile time, in fact I think it would be the latter.
Especially considering Strings are immutable, it's not like you can first get an empty String, and perform some operations on it - best to use a StringBuilder (or StringBuffer if you want to be thread-safe) and turn that into a String.
Update
From your comment to the question:
What inspired this is actually
TextBox.setText("");
I believe it would be totally legitimate to provide a constant in your appropriate class:
private static final String EMPTY_STRING = "";
And then reference it as in your code as
TextBox.setText(EMPTY_STRING);
As this way at least you are explicit that you want an empty String, rather than you forgot to fill in the String in your IDE or something similar.
Use org.apache.commons.lang.StringUtils.EMPTY
If you want to compare with empty string without worrying about null values you can do the following.
if ("".equals(text))
Ultimately you should do what what you believe is clearest. Most programmers assume "" means empty string, not a string someone forgot to put anything into.
If you think there is a performance advantage, you should test it. If you don't think its worth testing for yourself, its a good indication it really isn't worth it.
It sounds like to you try to solve a problem which was solved when the language was designed more than 15 years ago.
Don't just say "memory pool of strings is reused in the literal form, case closed". What compilers do under the hood is not the point here. The question is reasonable, specially given the number of up-votes it received.
It's about the symmetry, without it APIs are harder to use for humans. Early Java SDKs notoriously ignored the rule and now it's kind of too late. Here are a few examples on top of my head, feel free to chip in your "favorite" example:
BigDecimal.ZERO, but no AbstractCollection.EMPTY, String.EMPTY
Array.length but List.size()
List.add(), Set.add() but Map.put(), ByteBuffer.put() and let's not forget StringBuilder.append(), Stack.push()
Apache StringUtils addresses this problem too.
Failings of the other options:
isEmpty() - not null safe. If the
string is null, throws an NPE
length() == 0 - again not null safe.
Also does not take into account
whitespace strings.
Comparison to EMPTY constant - May
not be null safe. Whitespace problem
Granted StringUtils is another library to drag around, but it works very well and saves loads of time and hassle checking for nulls or gracefully handling NPEs.
Seems like this is the obvious answer:
String empty = org.apache.commons.lang.StringUtils.EMPTY;
Awesome because "empty initialization" code no longer has a "magic string" and uses a constant.
If you really want a String.EMPTY constant, you can create an utility static final class named "Constants" (for example) in your project. This class will maintain your constants, including the empty String...
In the same idea, you can create ZERO, ONE int constants... that don't exist in the Integer class, but like I commented, it would be a pain to write and to read :
for(int i=Constants.ZERO; ...) {
if(myArray.length > Constants.ONE) {
System.out.println("More than one element");
}
}
Etc.
All those "" literals are the same object. Why make all that extra complexity? It's just longer to type and less clear (the cost to the compiler is minimal). Since Java's strings are immutable objects, there's never any need at all to distinguish between them except possibly as an efficiency thing, but with the empty string literal that's not a big deal.
If you really want an EmptyString constant, make it yourself. But all it will do is encourage even more verbose code; there will never be any benefit to doing so.
To add on to what Noel M stated, you can look at this question, and this answer shows that the constant is reused.
http://forums.java.net/jive/message.jspa?messageID=17122
String constant are always "interned"
so there is not really a need for such
constant.
String s=""; String t=""; boolean b=s==t; // true
I understand that every time I type the String literal "", the same String object is referenced in the String pool.
There's no such guarantee made. And you can't rely on it in your application, it's completely up to jvm to decide.
or did the language creators simply not share my views?
Yep. To me, it seems very low priority thing.
Late answer, but I think it adds something new to this topic.
None of the previous answers has answered the original question. Some have attempted to justify the lack of a constant, while others have showed ways in which we can deal with the lack of the constant. But no one has provided a compelling justification for the benefit of the constant, so its lack is still not properly explained.
A constant would be useful because it would prevent certain code errors from going unnoticed.
Say that you have a large code base with hundreds of references to "". Someone modifies one of these while scrolling through the code and changes it to " ". Such a change would have a high chance of going unnoticed into production, at which point it might cause some issue whose source will be tricky to detect.
OTOH, a library constant named EMPTY, if subject to the same error, would generate a compiler error for something like EM PTY.
Defining your own constant is still better. Someone could still alter its initialization by mistake, but because of its wide use, the impact of such an error would be much harder to go unnoticed than an error in a single use case.
This is one of the general benefits that you get from using constants instead of literal values. People usually recognize that using a constant for a value used in dozens of places allows you to easily update that value in just one place. What is less often acknowledged is that this also prevents that value from being accidentally modified, because such a change would show everywhere. So, yes, "" is shorter than EMPTY, but EMPTY is safer to use than "".
So, coming back to the original question, we can only speculate that the language designers were probably not aware of this benefit of providing constants for literal values that are frequently used. Hopefully, we'll one day see string constants added in Java.
For those claiming "" and String.Empty are interchangeable or that "" is better, you are very wrong.
Each time you do something like myVariable = ""; you are creating an instance of an object.
If Java's String object had an EMPTY public constant, there would only be 1 instance of the object ""
E.g: -
String.EMPTY = ""; //Simply demonstrating. I realize this is invalid syntax
myVar0 = String.EMPTY;
myVar1 = String.EMPTY;
myVar2 = String.EMPTY;
myVar3 = String.EMPTY;
myVar4 = String.EMPTY;
myVar5 = String.EMPTY;
myVar6 = String.EMPTY;
myVar7 = String.EMPTY;
myVar8 = String.EMPTY;
myVar9 = String.EMPTY;
10 (11 including String.EMPTY) Pointers to 1 object
Or: -
myVar0 = "";
myVar1 = "";
myVar2 = "";
myVar3 = "";
myVar4 = "";
myVar5 = "";
myVar6 = "";
myVar7 = "";
myVar8 = "";
myVar9 = "";
10 pointers to 10 objects
This is inefficient and throughout a large application, can be significant.
Perhaps the Java compiler or run-time is efficient enough to automatically point all instances of "" to the same instance, but it might not and takes additional processing to make that determination.