Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
In Java, say I have an expression X that occurs multiple times in a function. Generally speaking, is it more efficient to create a variable and set it equal to X, or not use a variable at all? What are the advantages/disadvantages of each method?
Ex. Say X = 5+9*9-1000. Which function is more efficient, function1 or function2?
public void function1() {
System.out.println(5+9*9-1000);
System.out.println(5+9*9-1000);
}
public void function2() {
int variable = 5+9*9-1000;
System.out.println(variable);
System.out.println(variable);
}
Neither is more efficient. Your expression 5+9*9-1000 is a constant expression. The compiler will evaluate it at compile time and only the result shows up at runtime (-914).
The JLS defines constant expressions in Section 15.28. Basically it consists of literals, operators, and constant variables.
Often it's more convenient, readable, and expressive to have a constant expression rather than multiplying the values yourself.
int secondsPerDayCalc = 86400; // not obvious it's number of seconds in a day
int secondsPerDay = 60 * 60 * 24; // constant expression; more readable
There is no performance penalty, because it's evaluated at compile time.
Use a variable in this case or a function in more complicated cases. Yes, there may be an efficiency gain, but the real issue is the maintainability of the code. Repeated strings of characters like this create a source of potential errors if the expressions need to change.
Generally speaking, is it more efficient to create a variable and set it equal to X, or not use a variable at all?
Generally speaking, it is not possible to say. It may be more efficient. It may make no difference. It could conceivably even be less efficient. It all depends on what the JIT compiler does with the code, and that is dependent on the JVM you are using, the application, and even the input data.
(In your specific example, the expressions are constant expressions, and they will be evaluated at compile time. That makes the runtime efficiency issue moot.)
What are the advantages/disadvantages of each method?
To my mind, the most important issues are:
Readability. Splitting an expression into sub-expressions with temporary variables may make your code more readable. (It depends on the code complexity ... and the expected Java reading skills of the people who need to maintain your code.)
Side-effects. Some expressions involve side-effects. In this case, refactoring to use temporary variables may change the meaning of the computation.
The best general advice is to leave this kind of optimization to the JIT compiler. But if performance is an critical issue, and you do really need to optimize at this level, then you need to do it scientifically.
Benchmark your code (properly!) to establish a performance baseline.
Profile it to identify hotspots.
Modify the code to improve performance at a hotspot.
Rerun the benchmark to see if you have improved things.
Go to step two ...
(Optimizing based solely on your intuition, you are liable waste a lot of your time optimizing with minimal measurable performance benefits. Also bear in mind that hand optimizing for one platform does not necessarily improve performance on others ...)
Related
My java project uses objects that have an ArrayList of Strings. These strings are, however, predetermined. There are only 47 or so possible Strings. Now I want to check if an ArrayList contains a certain String.
I currently do this through .equals() , but I believe that's quite slow, so I want to switch to == (int). It is, however, quite annoying to manually turn all .equals() into == (int). Especially when things have to be changed again.
So is there a tool that turns all these .equals() to == (int) for a set of Strings?
Beware of premature optimisation (it's the root of all evil). There are plenty of resources describing this in detail. In short, it's important to measure the performance impact of any optimisation you make and weigh it against code readability. In this case, I would imagine you are reducing readability for negligible affect on performance.
It's also worth noting that accurate measuring performance is an entire subject on its own. It's difficult to get meaningful results if the differences are small because there are about a million factors other than the actual code which can affect performance - especially Java, with it's hotspot compiler.
Without seeing code, it's hard to appreciate your exact application. However, you may be able to improve performance without decreasing (or potentially improving?) readability by using enums in an EnumSet. Again, if improving performance is your primary goal, it's important to measure to see if your changes actually improve anything.
You may be also be able to simplify your existing String#equals code using [List#contains](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/List.html#contains(java.lang.Object)
If they are all predetermined can you just use an enum? Enums are basically a list of named numbers with some extra helper functions.
public enum myStrings
{
firstString,
secondString,
lastString
}
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 6 years ago.
Improve this question
do you prefer writing method with immediate return of result to assigning it firstly to variable? To be clear we only consider situation presented below when no other operations are done in method body.
First option:
private List<Integer> getIdsOfUsersLoggedWithinLastHour() {
return userDAO.getUsersLoggedWithinLastHour().stream().map(User::Id).collect(Collectors.toList());
}
Second option:
private List<Integer> getIdsOfUsersLoggedWithinLastHour() {
List<Integer> ids = userDAO.getUsersLoggedWithinLastHour().stream().map(User::Id).collect(Collectors.toList());
return ids;
}
IMHO there is no need to assign result of method operations to variable when you do nothing with it and just return. The return type is declared in method signature so you can easily check it. The code cleanliness is about the same. You use some additional memory and cpu operations (maybe not so important today but it is always something additional). Friend of mine claims that initializing variable is better for easier debugging and further code development but I think it is redundant and can be done when you really need this, not 'for future'. What is your opinion?
In many cases I plump for the second option and, in the cited case, I almost certainly would.
This allows you to place a breakpoint on return ids; which can be helpful when debugging. (Inspecting the contents of a CPU register is an option in low level languages like C, but I don't think that is available for JVM-based languages).
A series of functions that return an anonymous temporary up the stack can be difficult to debug.
I wouldn't worry about any overhead that the second choice introduces: that ought to be optimised out and declaring an extra reference variable is unlikely to cause a performance bottleneck even if it was not optimised out. (Note that in C++ it will be optimised out via a process called Named Return Value Optimisation and I imagine that Java would follow suit.) Remember that being able to debug and maintain code is as important as elegance; whatever that means in this particular instance.
I assign result to the variable only when need to do some logic with it before returning value from the method. Otherwise I use coding style from the first example - makes code concise.
Second code style can help during debug process sometimes, but you shouldn't commit this IMHO
Also, if you inspect second example with any popular static analysis tool it would give a result like "local variable is redundant" which is one more reason to eliminate those vars in real projects.
Good article about this design issue: http://www.yegor256.com/2015/09/01/redundant-variables-are-evil.html
But you must understand that it's only a common practice, nobody can make you do not use redundant variables - code works with them correctly, it's only a question of taste like many other design principles
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 7 years ago.
Improve this question
There is an explanatory code of what I'm trying to ask. Sureley, the difference between the codes below is ignorable, yet it describes the point.
Which one is the most efficient in terms of memory usage and performance?
if( MathUtil.CalculateSin(angle) > Angles.ACUTE){
// Something is done
}
or
double angleSin = MathUtil.CalculateSin(angle);
if( angleSin > Angles.ACUTE){
// Something is done
}
It simply depends if you are going to re-use the variable.
If yes, use the second case.
If no use the first case.
There is no reason to store the value in a variable if you are not going to re-use it.
Edit :
As per your comment, it seems you are mostly asking this question for performance concern...
Actually my question is not about the algorithm nor the way I
implement it. I'm curious about the memory usage of the approaches,
therefore efficiency is the purpose.
Don't expect any difference in term of memory usage for both approaches, the JVM and JIT will optimize it as much as possible so that both case become the same.
To extend the other answers, you should also consider readability of your code. In this case, the meaning of MathUtil.CalculateSin(angle) is pretty obvious. However, if you have a more complex condition, it would be a good idea to precompute that condition, give the variable a meaningful name and then use the variable in the if-statement.
In your case it also depends on the context of the if-statement. Again, MathUtil.CalculateSin(angle) > Angles.ACUTE is quite easy to grasp at a glance. However,
final boolean angleIsAcute = (MathUtil.CalculateSin(angle) > Angles.ACUTE);
if(angleIsAcute) { ... }
would carry the meaning better. In this case, of course, both possibilities are quite similar, but I hope you see where I am going with this.
Do not worry about the overhead that is introduced by storing that extra variable. Even though the java-compiler does not optimize your code, any JVM worth its salt will optimize the bytecode and the performance overhead will be negligible.
I often use the first pattern even when I won't need the variable later in the code. The advantage is for debugging.
You can examine and change the value of the variable when stepping through the code in a debugger.
If an exception occurs in the call on the right-hand side of the statement, it is sometimes clearer what happened than if the call is embedded in an if or as an argument to another call.
If you're concerned about memory usage for the variable, don't be. Trust the compiler to optimize away variables that it knows aren't going to be used later. If you declare the variable final, it will be optimized aggressively as described in the JLS.
References do take memory. So if you are not going to use angleSin anywhere else then second option is what you should go for. Besides it does not pollute the namespace. That is one reason people make Comparator as an anonymous class instead of creating a new one. If they do not need to use somewhere else.
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 7 years ago.
Improve this question
I read in a book (Fischer's Java Closures and Lambda, Apress 2015) that method references are preferable to lambda expressions. From my point of view, the lambda expression is more easily understandable to developers who use other languages. Then why does it say the method reference is preferable? Is writing a lambda expression a bad practice in Java 8?
In the Lambda Best Practices section of Chapter 2, Fischer's book says:
As much as possible, use a method reference instead of a lambda. Method references are not only shorter and easier to read, but using method references will get you thinking directly about the methods as values. This is the code you need to excise from your codebase and your brain:
x -> it.do(x)
If you are naturally writing that code, then you still have not made the leap to thinking at the higher level of functional programming. Once you make that leap, it will become much easier to communicate and work with complex functions, because you will be thinking in types, not in values.
Although I mostly agree with the conclusion, I'm not sure I buy Fischer's line of reasoning. Method references are often, though not always, shorter than the written-out lambda. In the first part he says that method references will help you think about methods as values. OK, but then later he says things will become easier because you'll be thinking in types, not values. I'm not sure what that means.
It's possible to rewrite the example expression he gives as
it::do
That's certainly shorter than the original, but it's hard to generalize from a tiny example.
Here's my take on method references vs. written-out lambdas.
If there is a choice between using a lambda expression and a method reference, it is often the case that a method reference is preferable. But this is not a hard-and-fast rule, and there are likely to be circumstances where a lambda expression is preferable. It's also somewhat a matter of taste.
If you're familiar with lambda expressions from other languages, then lambda expressions in Java will probably be more immediately familiar than method references. However, I believe this to be a temporary state until you learn method references. Once they're more familiar, the advantages of method references can outweigh the initial unfamiliarity.
Consider this simple example of getting the lengths of strings:
List<String> list = ... ;
int[] lengths1 = list.stream().mapToInt(s -> s.length()).toArray();
int[] lengths2 = list.stream().mapToInt(String::length).toArray();
In this case, the size of the lambda expression is just about the same as the size of the method reference (in the number of characters). But notice that the method reference contains more type information. It tells the reader that the element type is String, which may be helpful in understanding a long pipeline. It is sometimes also helpful to the compiler, if it cannot infer the element type, as sometimes occurs in complex expressions.
Another point is that, using a method reference will often relieve you of the responsibility of coming up with a name for a formal parameter that's simply passed to another method. Naming is often important, but lambda formals are often "garbage" names like i x or s as in this example.
The method reference is a tiny bit more efficient, as it doesn't need to generate a static method that must be called through to get to the String.length() method. But this efficiency is rarely an important consideration.
Consider also this example, deliberately stripped of context:
(x, y) -> x + y
Is this string concatenation or numeric addition? If numeric, what type? Under the rules of the language, this must be known at compile time, otherwise it's an error. Although it might be clear to the compiler, sometimes this isn't very clear to the reader. Consider instead these method references:
String::concat
Integer::sum
Double::sum
Using a name for the operation in this case makes it very explicit to the reader about what is intended.
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 8 years ago.
Improve this question
If I have a series of method invocations, the value of each used for the next call, should I store them in local variables, like so:
DynamicForm filledForm = Form.form().bindFromRequest();
String shareIdStr = filledForm.get("data[shareId]");
UUID shareId = UUID.fromString(shareIdStr);
Share share = Share.find.byId(shareId);
or as a single invocation chain, like so:
Share share = Share.find.byId(UUID.fromString(Form.form().bindFromRequest().get("data[shareId]")));
In this case, the only value that is used again is share. Perhaps the answer is somewhere in-between, or is something completely different. What's your opinion?
Not chaining Methods :
ADV
Enhances readability.
Gives an opportunity for re-usage.
Pin pointing exceptions (if any) becomes easier.
Debugging becomes easier, i.e. setting breakpoints on specific invocation is easy.
DisADV
Increases length( I wont say size :) ) of code.
IDE warnings (if any).
Chaining Methods
ADV
Reduces the need for creating multiple temp. variables.
Is a syntactic sugar
Reduces the number of lines to be written.
DisADV
Reduces readability of code.
Commenting becomes difficult (if any) for particular methods called.
Debugging the whole chain of invocation becomes very difficult.
The first way is only useful if you re-use these variables later in the method. If not, Eclipse will tell you they are not used. So the second way is better, I think.
To clarify a long line of code, I like to write it like this :
Share share = Share.find
.byId(UUID.fromString(Form.form()
.bindFromRequest()
.get("data[shareId]")
)
);
You can only compare these two forms if you consider you will not reuse variables. Otherwise, it doesn't make sense to compare them.
Generally the first variant gives your code more readability and potentially makes it easier to maintain.
Personally I develop a lot for embedded systems where the target platform has big constraints on computation power and size. Therefore I typically inline the code, so that my bytecode is smaller.
If I am to develop an application to run on a powerful server, or even the regular PC, then I would most likely opt for variant one.
Depends how you want to read your code. Local variables are useful if you are going to use them again. Otherwise proceed with chain invocation.