0

For example:

while (some_condition) {
  byte[] myArray = new byte[65536];
  ...do some array manipulate...
  ...
}

and

byte[] myArray = new byte[65536];
while (some_condition) {
  ...clear / system.arraycopy the myArray with 0
  ...then, do some array manipulate...
  ...
}

Which is more memory efficient OR speed benefit in Java JVM?

And when loop is deeper, extract inner-most local array to outer-most is ugly and hard to understand.

rufushuang
  • 302
  • 4
  • 17
  • The one which allocates less memory (2) is clearly the more memory efficient one. – Andy Turner Nov 01 '16 at 07:35
  • You can benchmark it. – mm759 Nov 01 '16 at 07:36
  • I think it's basically impossible to say in isolation. What you do is **if** you run into a problem with the method this is in, [benchmark](http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java) both ways to see if one of them solves the problem. I would probably instinctively write the first one, even though it violates my usual "variables should be scoped as narrowly as possible" dictum. – T.J. Crowder Nov 01 '16 at 07:37
  • The more garbage you create, the more memory pressure you place on the computer and your garbage collector. Note: your L1 data cache is 32KB so using a buffer of this size or less may be more efficient. – Peter Lawrey Nov 01 '16 at 07:54
  • @Peter Lawrey: how do you know the OP’s L1 cache size? – Holger Nov 01 '16 at 15:50
  • 1
    @Holger I assume the OP was using x86, x64, ARM or Sparc, but it could be something else, though the OP might want to make the buffer smaller anyway. – Peter Lawrey Nov 01 '16 at 15:52
  • @Holger Admittedly Pentiums before 1997 had a 16 KB L1 cache. In any case, it wasn't larger than 32 KB. – Peter Lawrey Nov 01 '16 at 15:55
  • 1
    @Holger sometimes you will see 64 KB L1 cache in which case it is likely to be 32 KB instruction and 32 KB data, or Windows might say 512 KB of L1 cache but this is likely to mean you have 8 cores, but each core has only 32 KB of L1 data cache. – Peter Lawrey Nov 01 '16 at 16:00
  • 1
    @Peter Lawrey: ok, I see your point, saying “your L1 data cache is most probably 32KB or less” would be more appropriate, but anyway, I wonder, if the OP has the option to change the array size at all. That would imply that it is indeed some sort of buffer, e.g. for I/O, which would render the idea of keeping it in the L1 cache moot, as well as the entire question, as the I/O will dominate the performance anyway… – Holger Nov 01 '16 at 16:00
  • @Holger when copying to/from in memory disk cache, I have seen the size of the buffer does matter, and making the buffer too small or too large hurts performance. – Peter Lawrey Nov 01 '16 at 16:02
  • @Peter Lawrey: of course, the buffer size may also matter for I/O, but the question isn’t about the buffer size at all. Perhaps it would be better to use a `ByteBuffer` then, which changes the entire relationship to Java’s memory management… – Holger Nov 01 '16 at 16:05
  • @Holger A direct ByteBuffer might be better (a heap ByteBuffer not so much) but again a smaller size is likely to be both more memory efficient and possibly faster. – Peter Lawrey Nov 01 '16 at 16:08

2 Answers2

1

In both cases the array will be zeroed, either explicitly by you (second case) or by the JVM after allocation (first case). However, in the first case since you're allocating memory each iteration, the overall memory pressure will be greater which may cause garbage collections (depending on exactly how many iterations you have, what else you're doing in the program and many other factors). This could slow you down compared to the second case.

So the second example should be more memory efficient. Overall runtime will depend on other factors like whether you caused a GC.

avivr
  • 1,393
  • 15
  • 28
  • 1
    There is yet another case where the first example is better (apart from better readability), namely if the loop is executed less than once on average. – Henry Nov 01 '16 at 07:50
0

There is a definite advantage in the amount of garbage you create. With the array extracted, it's zero, with the array inside the loop, it's O(n). Whether or not this fact makes a difference in the overall context, depends on that context. In some cases it is better to prefer simplicity, but there definitely are cases where eliminating garbage can bring important speed advantages. A further advantage of reusing the array is CPU cache locality.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • I don’t see, how the application will gain anything from “cache locality” when it is going to overwrite the entire array contents with zeros anyway. – Holger Nov 01 '16 at 15:43
  • By reusing the same cache lines. This causes much less cache coherence traffic. – Marko Topolnik Nov 01 '16 at 15:44