Thanks bearophile.

With respect to passing structs as reference, I also have this problem. In the widget, I have a opIndex method, that returns a ListViewItem given an index (like an array). When opIndex return the instance I'm looking for, and then I modify some property (a image index, for example) the change is only visible in the returned copy, but the internal instance, the one stored in the collection (array in this case) is not modified.

Now, about the speed. Currently, I'm not so concerned about speed. First I want to make this work correctly, and then profile to improve execution speed, etc. What worries me is the hypothetical case of a heap thrashed or severely fragmented because the several small allocations. Something that I don't mentioned in the previous message, is that in each item instance there's a string with the text to display. So not only I need to allocate for each item instance, but also allocate the text string for each one :D

I think the idea of a memory pool or freelist is good. Can you point me where can I see your libs?

Thanks again.

Yao G.


On Wed, 02 Jun 2010 19:18:37 -0500, bearophile <bearophileh...@lycos.com> wrote:

Yao G.:

Hello everybody.

What's the best practice or more efficient way to deal, in D, with lots of small objects? My problem is this: I have a small control, ListView. This
control can have hundreds (and theoretically thousands) of items
(ListViewItem instances, to be precise). And, in turn each one of this
ListViewItems can own sub-items (ListViewSubItem instances), effectively
creating an humongous quantity of small objects.

Should I just go and create all of those items as classes? I have the
feeling that this not very efficient (a lot of small heap allocations).
There's also the possibility of make them structs. But then I would have
the issue of passing value objects in methods and losing whatever change I made (because I would be modifying a copy of the original). To solve this I could make an internal, Impl structure, and then use reference counting
to manage the copies and to make effective all the item modification
across all copies. But then I would be where I started: doing tons of heap
allocations.

So, how should I deal with this issue?

First of all run your program and profile it. If it's fast enough for your purposes, or if the slow parts are elsewhere then you can avoid to optimize the allocation of all those objects.

Otherwise, or if you are writing library code it has to be fast regardless. If you can change those objects into structs, then it's "easy", you can pass them in functions by ref, keeping their changes, and you can allocate them in large chunks, using some kind of arena, pool or stack with a freelist, etc. In my dlibs1 I have something like this to allocate chunks of structs in a pool.

If you must use objects, then you can create the same pools, using placement new. Unfortunately placement new is now deprecated in D2 :-) (If you are using D1 it's OK). Andrei has recently shown a TightArray to replace placement new in D2, but I think it's not good enough yet to solve your problem (but I probably Andrei will improve it).

Bye,
bearophile


--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/

Reply via email to