this question is about java coding, my question is easy so i'll explain it with a little example :)
I have a String array full of arguments, and i have to check it's length several times, so, it's better to save the amount of arguments (array length) in a variable, or just call the length every single time?, i suppose that storing a variable will consume more memory, and the other way will use more cpu, just want to ask what do you think is better thanks!
Example:
String[] arguments = {"a","b","c"};
int numberOfArguments = arguments.length;
if(numberOfArguments == 1)do whatever
if(numberOfArguments == 2)do whatever
if(numberOfArguments == 3)do whatever
etc
OR
String[] arguments = {"a","b","c"};
if(arguments.length == 1)do whatever
if(arguments.length == 2)do whatever
if(arguments.length == 3)do whatever
EDIT: i know the difference will be really small.. but i'm asking for a LONG PROCESS, think big, a million of "arguments.length", so for that case i think is better to sacrifice a ultra small amount of memory to store the variable which should be better for the cpu than checking the arguments lenght a million of times than checking a variable value which is always the same, what do you think?
This is a premature optimization; do whatever you find more readable/easier to manage. Personally, I prefer to just refer to the length field directly because I see no point in storing it in another variable (unless, perhaps, the length of the array has a different meaning in the context of your program than simply a count of elements - in such a case it might be appropriate to store it in a reasonably named variable). In any case, you can rest assured that there will be no appreciable performance difference between the two.
By the way, array.length might even be faster in some cases (assuming you're able to see any time difference whatsoever) than storing the length in a local variable and using that instead. There's even a bytecode operand reserved specifically for this: be (arraylength), not to mention the optimizations that will be made along the way.
First of all: you can't compare storage with speed, those are different things.
What you can do is determine how much you value each. If you need 100% speed, you will go for the speed option and vice versa.
Usually you want an equal consideration, which brings us to this:
it's up to your own preference. Will you often access that property? Maybe it's interesting to store it in a variable.
See for yourself what you find easier to use: your example has very little influence either way. Retrieving the size of a list is already stored in a variable so there's no looping going on.
The difference in both is creating one extra variable versus getting length of array, the difference will depend on how you are using this code.
If you create a millions instances of this class, then in first approach you will be creating million variable and you can now think of memory being used more in first approach.
Reading length of array is not expensive, so in nutshell it really depend on how is this code being used in your project.
Leaving everything aside, since length is being used multiple times creating a variable is a good practice.
Cheers !!
Object oriented programming saves you having to do long if statements. Calculate the number of arguments once, and create an instance of the specific class for that scenario. Then you can call any method on that instance and it will act in a 'do whatever' manner for that situation.
(forgive my rusty Java...)
public interface Arguments{
void foo();
}
public class OneArgument implements Arguments{
public void foo(){
// do whatever
}
}
public class TwoArguments implements Arguments{
public void foo(){
// do whatever
}
}
public class ThreeArguments implements Arguments{
public void foo(){
// do whatever
}
}
Then you could have a factory method:
public static Arguments create(String[] args){
if(args.length == 1) return new OneArgument();
else if(args.length == 2) return new TwoArguments();
else if(args.length == 3) return new ThreeArguments();
else throw new Exception();
}
Better thought out architecture will most likely yield better performance in the long run.
Related
I have a method that list the elements of an ArrayList, typically it prints the components of a global variable ArrayList, but in one specific instance I need it to print the components of a local variable.
So I have this
public static void listPlayers(ArrayList<Player> characters, boolean beingRolled) {
//print character components (beingRolled specifies which parts of each players to print
}
and I use that when I'm using the local variable ArrayList,
when I want to use the global i call this version
public static void listPlayers(boolean beingRolled) {
listPlayers(players, abitraryBoolean);
}
where players is the global variable
Another thing I was thinking about is anywhere I want to use the global I could pass a null reference for characters and write this method
public static void listPlayers(ArrayList<Player> characters, boolean beingRolled) {
if (characters == null) characters = players;
//print components
}
Which is the more professional/recommended version?
In general, stay away from null; the overloaded method signature is a better approach.
That said, one thing you said is scary -- You have a static method operating on a global variable. In general, that is a bad idea. You should consider refactoring to use Object/class scoped state, rather than global, static scoped state.
I would even go so far as to say that you should only use the overload that takes the ArrayList as a parameter, and pass it the global variable every time. Then, even if you must use a global variable, at least you're using it in one fewer place.
Edit: One of my professors back in college wrote a book on refactoring that is very readable and has a lot of good content (though the typography is a bit odd). It's called Principle-Based Refactoring: Learning Software Design Principles by Applying Refactoring Rules, by Steve Halladay. I highly suggest reading the first half (second half is essentially a reference).
The first version is better because it is easier for someone else to understand. When a function's arguments are all listed, the caller can more easily predict what the function will do. If the function relies on variables which are not visible, say if this is available in a library without the source, the caller will not understand why the function acts in an unexpected way. This would be impossible to understand without good documentation.
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.)
As I understand, in case of an array, JAVA checks the index against the size of the Array.
So instead of using array[i] multiple times in a loop, it is better to declare a variable which stores the value of array[i], and use that variable multiple times.
My question is, if I have a class like this:
public class MyClass(){
public MyClass(int value){
this.value = value;
}
int value;
}
If I create an instance of this class somewhere else: (MyClass myobject = new MyClass(7)), and I have to use the objects value multiple times, is it okay to use myobject.value often or would it be better to declare a variable which stores that value and use that multiple times, or would it be the same?
In your case, it wouldn't make any difference, since referencing myobject.value is as fast and effective as referencing a new int variable.
Also, the JVM is usually able to optimize these kinds of things, and you shouldn't spend time worrying about it unless you have a highly performance critical piece of code. Just concentrate on writing clear, readable code.
The short answer is yes (in fact, in the array case, it does not only have to check the index limit but to calculate the actual memory position of the reference you are looking for -as in i=7, get the base position of the array and add 7 words-).
The long answer is that, unless you are really using that value a lot (and I mean a lot) and you are really constrained due to speed, it is not worth the added complexity of the code. Add to that that the local variable means that your JVM uses more memory, may hit a cache fault, and so on.
In general, you should worry more about the efficiency of your algorithm (the O(n)) and less about these tiny things.
The Java compiler is no bozo. He will do that optimization for you. There is 0 speed difference between all the options you give, usually.
I say 'usually' because whether or not accessing the original object or your local copy isn't always the same. If your array is globally visible, and another thread is accessing it, the two forms will yield different results, and the compiler cannot optimize one into the other. It is possible that something confuses the compiler into thinking there may be a problem, even though there isn't. Then it won't apply a legal optimization.
However, if you aren't doing funny stuff, the compiler will see what you're doing and optimize variable access for you. Really, that's what a compiler does. That's what it's for.
You need to optimize at least one level above that. This one isn't for you.
I commonly find myself writing code like this:
private List<Foo> fooList = new ArrayList<Foo>();
public Foo findFoo(FooAttr attr) {
for(Foo foo : fooList) {
if (foo.getAttr().equals(attr)) {
return foo;
}
}
}
However, assuming I properly guard against null input, I could also express the loop like this:
for(Foo foo : fooList) {
if (attr.equals(foo.getAttr()) {
return foo;
}
}
I'm wondering if one of the above forms has a performance advantage over the other. I'm well aware of the dangers of premature optimization, but in this case, I think the code is equally legible either way, so I'm looking for a reason to prefer one form over another, so I can build my coding habits to favor that form. I think given a large enough list, even a small performance advantage could amount to a significant amount of time.
In particular, I'm wondering if the second form might be more performant because the equals() method is called repeatedly on the same object, instead of different objects? Maybe branch prediction is a factor?
I would offer 2 pieces of advice here:
Measure it
If nothing else points you in any given direction, prefer the form which makes most sense and sounds most natural when you say it out loud (or in your head!)
I think that considering branch prediction is worrying about efficiency at too low of a level. However, I find the second example of your code more readable because you put the consistent object first. Similarly, if you were comparing this to some other object that, I would put the this first.
Of course, equals is defined by the programmer so it could be asymmetric. You should make equals an equivalence relation so this shouldn't be the case. Even if you have an equivalence relation, the order could matter. Suppose that attr is a superclass of the various foo.getAttr and the first test of your equals method checks if the other object is an instance of the same class. Then attr.equals(foo.getAttr()) will pass the first check but foo.getAttr().equals(attr) will fail the first check.
However, worrying about efficiency at this level seldom has benefits.
This depends on the implementation of the equals methods. In this situation I assume that both objects are instances of the same class. So that would mean that the methods are equal. This makes no performance difference.
If both objects are of the same type, then they should perform the same. If not, then you can't really know in advance what's going to happen, but usually it will be stopped quite quickly (with an instanceof or something else).
For myself, I usually start the method with a non-null check on the given parameter and I then use the attr.equals(foo.getAttr()) since I don't have to check for null in the loop. Just a question of preference I guess.
The only thing which does affect performance is code which does nothing.
In some cases you have code which is much the same or the difference is so small it just doesn't matter. This is the case here.
Where its is useful to swap the .equals() around is when you have a known value which cannot be null (This doesn't appear to be the cases here) of the type you are using is known.
e.g.
Object o = (Integer) 123;
String s = "Hello";
o.equals(s); // the type of equals is unknown and a virtual table look might be required
s.equals(o); // the type of equals is known and the class is final.
The difference is so small I wouldn't worry about it.
DEVENTER (n) A decision that's very hard to make because so little depends on it, such as which way to walk around a park
-- The Deeper Meaning of Liff by Douglas Adams and John Lloyd.
The performance should be the same, but in terms of safety, it's usually best to have the left operand be something that you are sure is not null, and have your equals method deal with null values.
Take for instance:
String s1 = null;
s1.equals("abc");
"abc".equals(s1);
The two calls to equals are not equivalent as one would issue a NullPointerException (the first one), and the other would return false.
The latter form is generally preferred for comparing with string constants for exactly this reason.
I have a method that takes 5 double values and performs an action with them. Right now the argument list is five different doubles. Is there any way to pass a double[] as an argument to the method but make sure its length is exactly 5?
One way is this:
private void myMethod(double[] args) {
if (args.length == 5) {
// do something
}
}
but is there a better way?
If you know you need exactly 5 doubles, then I think you are better off asking for 5 distinct doubles. Having them listed out with meaningful names it will still be hard enough (even with intellisense or whatever it's called) to keep the order of the variables straight. If they are in an array, the user will need to consult the documentation to see which value should go in which index.
No. You can't restrict the length of an array passed to a function.
If your goal is to keep the checking code out of the method so it's cleaner, you could delegate the real work to another method.
If your concern is the length of the parameter list you could pass a parameter object.
You could create a class which is a specialization of a Vector limited to 5 doubles, but it seems like overkill. I would just throw an exception if there are too few or too many entries in the array - this is likely a programming problem rather than a runtime exception.
You could put your code in try-catch block. This provides to miss an unnecessary check.
But if something doing wrong you could avoid the problems with exception.