[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [computer-go] space efficiency in C++



I'm using C++, and I have a class: tree, that contains a member object list<tree *> children. I think I do want a list here, because I do a lot of deleting individual elements. My tree objects are very big, in fact their size is the main performance limiting factor in my programme. However, the lists of children are typically quite short, often one or two elements. My implementation of the Standard C++ Library seems to allocate space for each list in batches of 256 links (which I suspect is typical).
The underlying list node allocator will probably get a whole bunch of nodes every times it needs more nodes (probably the number of nodes that fit in a memory page). In your case, the node size seems to be 4096 / 256 = 16 bytes. Since you call them "links", I assume you use lists of pointers (i.e. list<T*>). The link holds 2 pointers (one for the linked list, the other one for your T objects). There is probably another hiden pointer used by the memory manager, and alignment makes your link 16 bytes large.

This leads to my tree occupying about 100 times as much space as it should.
However, a bunch of nodes shall not be tied to a given list, so your statement seems to be very odd (if it's true, you'd better use another implementation of the STL...).

Has anyone else come across this problem Does anyone have an idea for a work-around? Do I have to abandon the standard library for this application?
1. Make sure you really use "100 times as much space as it should". One way to do this is to trace node allocation (display their address on standard output and look at the difference between 2 consecutive allocations)
2. If yes (which would really surprise me), report to the library maintainer and / or use another implementation (what implementation are you using?)
3. Otherwise, you might consider:
a- storing objects instead of pointers in the list (use list<T> instead of list<T*>). Depending on sizeof(T), that might improve space efficiency
b- write your own allocator, and use it as an extra parameter to the template: this way, you can easily improve space efficiency, without rewriting the "list" class.
c- rewrite a whole tree class, that does not use lists from the STL

Your choice depends on your perspective. If you're writing experimental code and if efficiency is not the bottleneck (provided it remains decent), you'll go through steps 1 and 2 (and maybe 3a). If efficiency really matters then you might consider step 3c.

Another thought: if you are using list of pointer (list<T*>) don't forget that the list will only deallocate its own nodes (i.e. the links), and not the objects they point to. Since the objects have not been created by the list, they will not be deallocated by the list. Maybe you are experimenting memory leaks as well. In other words, if you write:

T* item = new item (...);
list<T*> l;
l.push_front (item);

and if you remove items from the list, and/or destroy the list, then you need to deallocate 'item' explicitely.

Antoine
_______________________________________________
computer-go mailing list
computer-go@xxxxxxxxxxxxxxxxx
http://www.computer-go.org/mailman/listinfo/computer-go/