QString's implicit sharing - how does it work, so I can know when I should be benefitting from it.
-
I have a whole heap of code that spends a significant amount of time constructing and destructing QStrings. No worries, thought I; I happen to know that many of those QStrings are actually the same, so I can eliminate all the unnecessary copies of them.
Then I found that QString is already implicitly shared, so I thought that it already should be using just one copy of each different QString, but that doesn't seem to be happening. Does anyone know more about the QString implicit sharing than the docs explain?
For example, how about this:
@QString alpha("Beans");
QString beta("Beans");@
Those will be shared data, I expect.So how about this as well
@QString gamma("Eggs");
gamma = "Beans";@
So I made another QString, gamma, that began life completely different, and then changed it so it's the same as an already existing QString. So will THAT now be shared data?
And then how about
@gamma = alpha;@
That surely should now be shared, even if it wasn't before?And other questions; is it ALL QStrings over the entire process, or is it more restricted - perhaps by class, or translation unit, or some other such? And how about static QStrings, and ones I make on the heap, and ones in the stack, and temporaries that never even have a name?
I really just need to know much more about how it works so I can work out if my code is, or should be, getting the benefit of it of not. Does anyone have information that can help fill in the gaps?
-
Hi,
[quote]
@
// NOT shared
QString alpha("Beans");
QString beta("Beans");
QString gamma("Eggs");
gamma = "Beans";
@
[/quote]Here, you created 3 completely independent QStrings. They do not share any memory, despite the fact that their contents are identical.(In order for the above to result in shared memory, every time you create a new string, Qt would need to compare your new string to all the strings that already exist -- that's way too expensive!)
To make different instances share memory, you need to refer to the original when making a copy:
@
// Shared
QString alpha("Beans");
QString beta(alpha);
QString gamma = beta;
@[quote]And other questions; is it ALL QStrings over the entire process, or is it more restricted – perhaps by class, or translation unit, or some other such? And how about static QStrings, and ones I make on the heap, and ones in the stack, and temporaries that never even have a name?[/quote]Memory can be shared between all strings in a process, as long as you create a copy by referring to the original (or by referring to any other copy).
All QStrings store their data on the heap.
(The possible exception to what I just said are strings constructed through QStringLiteral -- these are created during compile-time in read-only memory, and I'm not sure if they take part in the reference-counting system.)
-
That's perfect, thank you; they will be shared objects when it's explicitly clear that I make one a direct copy of another.
bq. (In order for the above to result in shared memory, every time you create a new string, Qt would need to compare your new string to all the strings that already exist — that’s way too expensive!)
That is, indeed, exactly what I'm about to do, albeit through the creation of a hash table of some kind of ref. counted QStrings, keyed by something relatively simple; if it exists, you get a pointer to it, if it doesn't, it gets made and then you get a pointer to it. In my particular case, the performance hit may well be preferable to the memory hit (and depending on how expensive it is to create a QString, once I've got a fair sized pool of them, it might get pretty fast anyway).
-
Then you'll be interested inn the benchmarks presented at http://qt-project.org/forums/viewthread/35934 :)
-
I will give that a read; looks good. I'm generating a couple of million objects containing at least one QString each, but there are only a few thousand unique QStrings in play.
Edit: I know, I know. Perhaps a better way to say it is I'm being presented with a couple of million objects containing at least one QString each, but there are only a few thousand unique QStrings in play.