I'll assume that most allocations relate to the list of objects you're talking about. If you're actually allocating a bunch of other objects as part of the parsing that's too slow, then you need more information to optimize.
I don't know anything about the RogueWave collections, but if their linked list allocates an external node, then you should be able to halve the number of allocations by using an intrusive list - write your own container if necessary. This assumes that you don't need to put the same objects on multiple lists at once (or in the same list more than once).
If your app is multi-threaded, then the memory allocator will likely be doing some synchronization. But if you can arrange for these objects to be freed in the same thread they're allocated, then they could be allocated off a per-thread heap by overloading operator new. This might be faster: synchronization isn't necessarily all that slow provided there isn't contention, but it takes more time than none, and if other threads in your process are allocating at the same time then there will be contention.
For even more limited use-cases, if you find that you allocate a whole load of these things and then always free them all at once when you're done with the list, you can write an even faster "gc-style" allocator.
Operator new/delete would call functions like these (and size might be a constant rather than a parameter, if there's only one class you use the pool for):
char *alloc(POOL *pool, size_t size) {
// if size is a parameter, and may be a non-multiple the max alignment
// requirement on your system, and you want this to work in general:
// size = (size + MAX_ALIGNMENT - 1) % ALIGNMENT;
char *block = pool.current;
char *next = block + size;
if (next > pool.limit) throw std::bad_alloc();
pool.current = next;
return block;
}
void free(char *block) {
return;
}
void freeAll(POOL *pool) {
pool.current = pool.start;
return;
}
This should ensure that operator new takes trivial time compared with what you spend parsing the objects you're creating. But it does require the application to identify the times at which it should create, destroy, and clear pools, and to to use a suitable new operator taking the pool pointer as a parameter, so it's not a drop-in replacement.