I have a class that uses boost::variant to store a double or a string, like this :
class value
{
boost::variant<double, std::string> val;
};
It's supposed to be an immutable value type for a toy interpreter I'm playing with. At first it seemed like a good idea to pass it around by const reference and return by value, and have it allocated on stack always, since I wanted it treated as a primitive. However, then I saw that it's size is 40 bytes (due to sizeof std::string, mostly), and I was a bit worried. I know I shouldn't allocate large chunks of memory on stack, but how large is too large?
Also, copying 40 bytes every time I return, especially since the value is immutable and doesn't even need to be copied, seems like a bit of a waste.
The option regular heap allocation doesn't seem too attractive, as I could have thousands of these allocations/deallocations per second.
The final option I came up with is to have a boost::pool to allocate these objects when needed, and use a boost::shared_ptr to manage their lifetime. However, because the interpreter is in charge of memory allocation (the type of memory allocation will be a policy passed to the interpreter as a 开发者_如何学Ctemplate argument), this would mean that the value class would have to know about the interpreter, which slightly complicates things.
So these are the questions :
- What should I do in this case and why?
- How big is "too big" to allocate on stack? I'm sure that depends on how often it's allocated and how often it has to be copied, too.
Thanks.
- What should I do in this case and why?
As always, write the program so that it is easiest to understand. If profiling later uncovers that this is indeed a problem, you can always turn value::val
into some dynamically allocated object later. (Of course, this presumes val
to be abstracted away well enough for this to not to affect any of the class' clients.)
- How big is "too big" to allocate on stack? I'm sure that depends on how often it'sallocated and how often it has to be copied, too.
It also depends on what platform you're on. Are we talking about the 8bit embedded chip running your toaster or a 64bit workstation?
IMO in the end it boils down to: It's too big if it creates problems due to its size.
If you really need to optimize this, I would recommend not using std::string
on Windows.
For immutable strings, a copy-on-write like implementation (basically, all copies of the string share the same internal buffer) could easily be implemented on top of shared_ptr
.
Since then you would only need a single pointer in your ConstString
class, you would not have to worry about passing by copy.
精彩评论