Dominik Seichter wrote: > Regarding the pool memory which has to be free'd explicitly with > boost::singleton_pool<boost::fast_pool_allocator_tag, > sizeof(TRefCountedBuffer)>::release_memory(). Maybe it is time to add > podofo_library_init() and podofo_library_free() method (or something similar) > which can be used by applications to clear any allocated memory in pools from > PoDoFo.
I tend to agree with that. I need to look into whether it's safe to then continue using the singleton allocators (say, after another podofo_library_init()) though, or whether that closes things down for the life of the process. > I just played a bit with ParserTest and callgrind. For the PDFReference I get A side note: Are you familiar with the `massif' tool of Valgrind? Very impressive. It generates a mapping of memory allocation hotspots and a nice graph showing proportionally how much memory was allocated in the various places. > 3 647 953 calls to new from PdfVariant::operator= > 1363133 calls to new from __gnu_cxx_new_allocator<PdfObject)::allocate > 2285072 calls to new from std::string::_Rep_S_create > 1453340 calls to new from > __gnu_cxx_new_allocator<std::_Rb_tree_node<std::pair<PdfName,PdfObject*>>::allocate > > (i.e. PdfDictionary::AddKey) > 893477 calls to new from PdfDictionary::operator= > > new is the function called most after malloc and free, but I guess this is > because new uses malloc internally. Well, and because PoDoFo uses malloc directly in a quite a lot of places. BTW, while I haven't confirmed this in detail the libstdc++ docs say that it actually caches memory internally, so not every call to operator new() necessarily results in an underlying memory allocation from the C library. If that's the case, it might well explain why we're not seeing much of a benefit from the Boost memory pools - though I'd expect them to at least be faster (by virtue of their specialization) than the method new() is using. libstdc++'s allocation behavior has changed many times though, so who knows how up to date the docs are. > I see that this is a very special test and very different from creating a > PdfFile or working with streams. But I think we coulg gain more from a > PdfVariant and PdfObject allocator. Maybe also from a pool for > std::_Rb_tree_nodes. One of the very nice things about the boost pool library is how easy that is to do. If you have: std::map<K,V> you can write: #if defined(HAVE_BOOST) typedef boost::fast_pool_alloc<std::map<K,V>::value_type> MapAllocator; #else typedef std::allocator<std::map<k,V>::value_type> MapAllocator; #endif std::map<K,V,MapAllocator> This works, for example, in PdfDictionary. It's even easier for single value containers (like PdfArray). All that changes for bulk-allocating containers is that you use pool_alloc rather than fast_pool_alloc, and nothing at all changes for individually allocating containers like std::list . I suspect, though, that gcc's libstdc++ is doing such a good job with the existing allocator functions that we're not going to see as much benefit as I initially thought. I'm particularly confused about the lack of benefit for the two *incredibly* common classes TRefCountedBuffer and PdfReference. Especially PdfReference, which is tiny and allocated in huge numbers, should benefit from using the pool allocator - yet in tests I see little change. I need to do some testing on Windows, too, but that's harder due to the fact that I don't have the same sort of tools available. -- Craig Ringer ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Podofo-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/podofo-users
