6

For Android development in general, is it more expensive to do the following: (Example 1)

for(int x=0; x < largeObjectCollection.size(); x++){
    largeObjectCollection.get(x).SomeValueOne   = "Sample Value 1";
    largeObjectCollection.get(x).SomeValueTwo   = "Sample Value 2";
    largeObjectCollection.get(x).SomeValueThree = "Sample Value 3" ;
    //Continues on to over 30 properties...
}

Over this implementation (Example 2)

for(int x=0; x < largeObjectCollection.size(); x++){
   SampleObjectIns myObject = largeObjectCollection.get(x);
   myObject.SomeValueOne   = "Sample Value 1";
   myObject.SomeValueTwo   = "Sample Value 2";
   myObject.SomeValueThree = "Sample Value 3" ;
   //Continues on to over 30 properties...
}

I couldn't find any break down of performance implications when using .get() multiple times instead of creating a new instance of that object each iteration.

I'm thinking that .get() doesn't use much in terms of resources since the position of the element is already known, but when dealing with many properties is it best to just fetch that object once as shown in example two?

Dayan
  • 7,634
  • 11
  • 49
  • 76
  • For an `ArrayList` (or other `RandomAccess` class), the performance difference is going to be minimal. Of course, using an enhanced for loop would be tidier, if you don't otherwise need `x` `for (SampleObjectIns myObject : largeObjectCollection) {`; but that's basically the second way. – Andy Turner Feb 24 '17 at 14:37
  • @AndyTurner Thanks, I was reading an article from 2015 (https://blog.jooq.org/2015/02/05/top-10-easy-performance-optimisations-in-java/) that points out iterators are practically not efficient, bullet #3. This got me thinking of my code which mostly uses `enhanced-for-loops` and thus this question came up. Do you recommend any books that cover these subjects well? – Dayan Feb 24 '17 at 14:51
  • first line of that point: "Now, this advice is really not for general use-cases". First line of your question: "For Android development in general". – Andy Turner Feb 24 '17 at 15:07
  • @AndyTurner Good point – Dayan Feb 24 '17 at 15:34

3 Answers3

3

There is no performance impact of calling get() method several times in a looping construct.

The get() method doesn't do any searching kind of stuff. The position is known, hence the exact location in the RAM is also known. So all it needs to do it make a single RAM access which is a constant time operation - O(1).

So, you can use it multiple times without any performance impact. But a much cleaner approach would be to use get() once, store it in a local variable and them re-use that variable.

Aritra Roy
  • 15,355
  • 10
  • 73
  • 107
  • Same comment I made on Divers' answer: "No, it's not to do with it being O(1), because the list's size isn't changing between the two cases. An operation which is O(n) (or worse) can take less time than another operation which is O(1), for some fixed n. Big-oh is asymptotic analysis: it doesn't mean anything when you've got a fixed size input.". – Andy Turner Feb 24 '17 at 15:08
1

The first case is clearly the one which would do more work. There are at least two possibilities:

  • The JIT might be able to determine that the list values aren't changing, and that you're requesting the same value repeatedly; and thus it effectively converts it into the second form.
  • The ArrayList.get operation is just really fast; it's basically just doing an array lookup, and the value it looks up is in cache already because you've just looked it up.

    So, your timing measurement is dominated by the other work that you're doing. So, even if you're doing 29 more get calls than necessary, 30 times a tiny number is still a tiny number.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • Good break down. I wasn't aware of the JIT being able to determine that values aren't changing and converting over to the second form. "your timing measurement is dominated by the other work that you're doing." - I will keep this in mind and switch back to my enhanced for loop. – Dayan Feb 24 '17 at 15:41
0

Only reason is that, get operation is really fast for array, that's why there is almost no notable difference in performance.

Divers
  • 9,531
  • 7
  • 45
  • 88
  • 2
    Both having the same time complexity does not mean they have no difference in performance. Something that takes 1 second whatever the input size is obviously worse than something that takes 1us whatever the input size; but they're both O(1). – Andy Turner Feb 24 '17 at 14:40
  • Didn't get you. Both what? – Divers Feb 24 '17 at 14:41
  • 1
    He is asking why there almost no difference with using `get` operation 30 times with using `get` operation 1 times. Im answering him that because `get`operation doesn't depend on size of a list and because it's really fast operation, that's why he will not see notable difference. – Divers Feb 24 '17 at 14:45
  • 2
    Right; but your explanation doesn't describe this. You state that the fact there is no difference in performance is because it's O(1), which is not the reason. The reason is *it's fast*, and the time taken to do other things dominates. – Andy Turner Feb 24 '17 at 14:48
  • You are right, but O(1) is reason as well, because in case if it would be O(N), you can not say **it is fast**, because on list with infinite size you will end up with infinite execution time of of `get` command. – Divers Feb 24 '17 at 14:52
  • 2
    No, it's not to do with it being O(1), because the list's size isn't changing between the two cases. An operation which is O(n) (or worse) can take less time than another operation which is O(1), for some fixed n. Big-oh is *asymptotic analysis*: it doesn't mean anything when you've got a fixed size input. – Andy Turner Feb 24 '17 at 14:55