This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
The performance of toArray() will be dominated by the time it takes to copy the original list elements over. ArrayList actually uses System.arraycopy() to do this, which is a fast routine. You're really not going to do any better.
Maybe you could just not call toArray() so much? Why are there so many calls? Can you rework some code to operate directly on the lists?
[EFH]: The performance of toArray() will be dominated by the time it takes to copy the original list elements over.
In general, I would agree. But I think it's also possible that, if this method is called many, many times, for arrays that are fairly short, the performance might instead be dominated by things like Class.getComponentType() or Array.newInstance() - both of which are quite unnecessary in this case. But they're needlessly invoked by a call to toArray(), if the provided array size is too small to contain the contents of the list. Really - if you' want to copy a list to an array, you should at least provide a list big enough to contain the contents of the list.
I suggest replacing
Of course I hope that these are just fragments of statements, not attempts at complete statements. Despite the fact that they look like, and can be interpreted as, standalone statements. Because if these were standalone statements, you'd be losing the benefit of the statements entirely. There's no reference to the new array you're creating. Probably an oversight. But to be more specific, I suggest the following:
The important points here are that (a) we store a reference to the new array, in the variable myArray, and (b) since the array object referenced by myArray is large enough to contain the contents of objectList, toArray() simply populates the existing array, rather than creating a new one. If we'd used a new MyObject, we'd have been guaranteed that (a) toArray() would have created a new object rather than reusing the existing one, and (b) toArray() would have needed to use some reflection to figure out the class of the new object to create. Which would be a waste of time. For large arrays, such a waste is insignificant. But for small arrays, created many times, it might be significant. [ November 14, 2008: Message edited by: Mike Simmons ]
It's really, really hard to let go of the deep-seated idea that memory allocation is slow. We're all so used to hearing that over the years. The amazing thing about modern JVMs is that allocation is actually insanely fast -- just a few clock cycles. The allocator doesn't worry about "free lists" or anything like that -- it literally just offsets a pointer to the top of the heap, and returns the result.
Of course, eventually you have to pay the piper -- the garbage collector has to deal with moving objects and compacting memory. But it turns out that that altogether, alloc/free in Java is still an order of magnitude faster than the typical C allocator.
That said: yeah, I usually pass the right-sized array, too. It can't hurt!
Author and all-around good cowpoke
Joined: Mar 22, 2000
The amazing thing about modern JVMs is that allocation is actually insanely fast -- just a few clock cycles. The allocator doesn't worry about "free lists" or anything like that -- it literally just offsets a pointer to the top of the heap, and returns the result.
Are you saying that the JVM no longer zeros out the allocated block of memory? I was under the impression that this was one of the security precautions that prevent Java from examing memory left over from other programs.
Actually, that type of allocation was at the heart of Macintosh memory management as well. The problem was heap compaction. But JVM's are dynamically adjusting their internal resources all the time anyway.
As far as zero-before use, I make no assumptions, not having looked into the innards of popular current JVMs. There are several ways to accomplish that trick, including JIT. An IBM mainframe for example can zap a large chunk of memory in a single instruction (so can many microproccessors, IIRC). Though I'd probably subdivide that task to avoid over-eager overhead.
An IDE is no substitute for an Intelligent Developer.