aspose file tools*
The moose likes Performance and the fly likes arraylist toarray performance Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Performance
Bookmark "arraylist toarray performance " Watch "arraylist toarray performance " New topic
Author

arraylist toarray performance

r per
Greenhorn

Joined: Nov 14, 2008
Posts: 1
Hi,

On profiling my application I found out that my algo is spending a lot of time in ArrayList.toArray() method. In particular I am making the following call,

(MyObject[])objectList.toArray(new MyObject[0]);

where objectList is an array list. Is there a way I can optimize the toArray() call.

Thanks
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Hi,

Welcome to JavaRanch!

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?


[Jess in Action][AskingGoodQuestions]
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3018
    
  10
[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

with

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[0], 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 ]
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12835
    
    5
I make it a practice to hand toArray the correct size of target array. Instead of:



I use:



this avoids some reflection steps in the toArray method for the case in which the supplied array is too small. (from Java 1.5 ArrayList class)



I dunno if it makes a measurable difference but it make me feel better.


Bill
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

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!
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12835
    
    5
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.

Bill
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16305
    
  21

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.


Customer surveys are for companies who didn't pay proper attention to begin with.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: arraylist toarray performance