Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString
On Thu, Feb 20, 2014 at 12:07:44PM -0800, Thiago Macieira wrote: Em qui 20 fev 2014, às 19:56:42, Oswald Buddenhagen escreveu: what are you planning to do? This is the first step: remove setSharable so we have one fewer state to check during ref up down. Keeping isSharedWith is no problem, as it doesn't affect the refcounting. The second step will be to use null d-pointers to indicate static data. That means Q{String,ByteArray}Literal() and Q{String,ByteArray,Vector}::fromRawData() don't have to have a d-pointer. For the latter, it has the extra benefit that fromRawData() won't allocate memory at all. ah, you are thinking qt 6 here. Obviously, if the d-pointer is null, neither the pointer to the data nor the size can be inside the d pointer. That means we have to extract the begin and size from inside the d-pointer and move to the actual class. another advantage of that model is that shared substrings would be rather cheap, which means that my fromRawData() magic could be dropped, and the existence of QStringRef could be re-evaluated (there is still the refcount, but that may be insignificant in the bigger picture on modern hardware). The third step will be to investigate whether Small String Optimisation makes sense. my guess is that it is not worth the effort. in most cases where you are dealing with non-constant short strings you are dealing with substrings with a very limited lifetime, which would be well covered by the previous point. and you have all the branches to deal with the denormalized strings which make read-only operations slower. anyway, have fun finding out. ;) ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString
On Thursday 20 February 2014 08:32:54 Thiago Macieira wrote: Please raise your hand if you knew we had that feature. I'm sure you know that COW implementations that hand out references to shared state need the sharable flag[1]. So are we talking about removing the public part of the API? Thanks, Marc [1] http://stackoverflow.com/questions/2526974/qt-undocumented-method- setsharable/11108588#11108588 -- Marc Mutz marc.m...@kdab.com | Senior Software Engineer KDAB (Deutschland) GmbH Co.KG, a KDAB Group Company www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090 KDAB - Qt Experts - Platform-Independent Software Solutions ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString
Em sex 21 fev 2014, às 16:49:39, Oswald Buddenhagen escreveu: ah, you are thinking qt 6 here. Yes. I'd rather do the deprecation as soon as possible so we can have a smoother transition when we come to it. Obviously, if the d-pointer is null, neither the pointer to the data nor the size can be inside the d pointer. That means we have to extract the begin and size from inside the d-pointer and move to the actual class. another advantage of that model is that shared substrings would be rather cheap, which means that my fromRawData() magic could be dropped, and the existence of QStringRef could be re-evaluated (there is still the refcount, but that may be insignificant in the bigger picture on modern hardware). Indeed. And since QByteArrays will be cheap for constant data, one of the changes should be to remove the QByteArrayLiteral stuff that moc is carrying. For Qt 6, we can go back to a plain string table and only record the length. That's another of the patches that I've been carrying for 2½ years. But to do what you're asking, we have to revisit the problem of the terminating null. Any sub-string (except right()) will not have terminating nulls. That might become a big problem. The other thing I'll need to investigate is the null-vs-empty distinction. Right now, they're distinct because we have a special value for the d pointer for a null object. If I remove the is static check on the refcount, I'll need to store the distinction somewhere. Options I can think of: 1) keep a non-null d for an empty-but-not null object (size == 0) a) d points to a read-write section of memory where we can ref up and down drawback: slowness due to atomic operations in multiple cores b) d points to another special value, like d = 0x1 bool isStatic() const { return (quintptr(d) ~1) == 0; } /// Returns false if deallocation is necessary bool deref() { return isStatic() || d-deref(); } 2) keep a null d for static empty, but a non null begin pointer bool isNull() const { return d == nullptr b == nullptr; } bool isEmpty() const { return size == 0; } T *constData() const { return b; } drawback: constData() would return nullptr for a null object, which would allow people to start relying on that. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString
Em sex 21 fev 2014, às 20:11:20, Marc Mutz escreveu: On Thursday 20 February 2014 08:32:54 Thiago Macieira wrote: Please raise your hand if you knew we had that feature. I'm sure you know that COW implementations that hand out references to shared state need the sharable flag[1]. So are we talking about removing the public part of the API? Yes. I am talking about removing a method from accessible API (undocumented → private) in Qt 6. As for creating a container pointing to non-permanent raw data, I think the solution of creating a deleter function makes more sense. [1] http://stackoverflow.com/questions/2526974/qt-undocumented-method- setsharable/11108588#11108588 The URL says undocumented method. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString
Em qui 20 fev 2014, às 16:45:19, Tony Van Eerd escreveu: -Original Message- On Behalf Of Thiago Macieira Subject: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString ... and removing them in Qt 6 Please raise your hand if you knew we had that feature. They aren't even documented, are they? (ie http://qt-project.org/doc/qt-5.0/qtcore/qvector-members.html ) And I couldn't find it on QString http://code.woboq.org/qt5/qtbase/src/corelib/tools/qstring.h.html I'm guessing they're not. what about: detach() isDetached() isSharedWith() couldn't all these be noops and/or return true/false, etc, without breaking any code? Isn't that the point of COW - you don't need to know? I agree on detach(): you can easily trigger a detach() by calling data(). Well, as long as you ensure that your object is not const. But we can't remove it because it's used by everything that does detaching. For example: T *data() { detach(); return d-data(); } The others are obscure indeed. As part of my efforts, I want to make QString / QByteArray / QVector keep a null d pointer for anything that doesn't require deallocation and reference counting -- that is, everything that is a static literal and the null / empty situations. If I do that, then: QString hello = QStringLiteral(Hello); QString world = QStringLiteral(World); hello.d == world.d == nullptr; So is hello.isSharedWith(world)? So I agree with you, we should also deprecate isSharedWith. As for isDetached(), I have a use for it right now: QByteArray QString::toLatin1_helper_inplace(QString s) { if (!s.isDetached()) return s.toLatin1(); // We can return our own buffer to the caller. // Conversion to Latin-1 always shrinks the buffer by half. const ushort *data = reinterpret_castconst ushort *(s.constData()); uint length = s.size(); // Swap the d pointers. // Kids, avert your eyes. Don't try this at home. [...] } -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString
I agree on detach(): you can easily trigger a detach() by calling data(). Well, as long as you ensure that your object is not const. I wouldn't get rid of detach() just because data() can do the same thing. If it is useful, I'd rather use the proper name for it. The question is whether it is useful... But we can't remove it because it's used by everything that does detaching. For example: T *data() { detach(); return d-data(); } ... for *public* use. It obvious it useful as a private function. As for isDetached(), I have a use for it right now: QByteArray QString::toLatin1_helper_inplace(QString s) { if (!s.isDetached()) return s.toLatin1(); // We can return our own buffer to the caller. // Conversion to Latin-1 always shrinks the buffer by half. const ushort *data = reinterpret_castconst ushort *(s.constData()); uint length = s.size(); // Swap the d pointers. // Kids, avert your eyes. Don't try this at home. [...] } That's also private use. So detach() and isDetached() could be private functions. The (philosophical) question is If it is useful privately, might it also be useful publicly? If so, why keep the power away from clients? (And there are various answers to each of those questions, in general.) Tony ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString
On Thu, Feb 20, 2014 at 09:12:29AM -0800, Thiago Macieira wrote: The others are obscure indeed. As part of my efforts, I want to make QString / QByteArray / QVector keep a null d pointer for anything that doesn't require deallocation and reference counting -- that is, everything that is a static literal and the null / empty situations. If I do that, then: QString hello = QStringLiteral(Hello); QString world = QStringLiteral(World); hello.d == world.d == nullptr; So is hello.isSharedWith(world)? So I agree with you, we should also deprecate isSharedWith. i introduced it for use in qmake/library/, to support an elaborate fromRawData() optimization. it wouldn't matter if it wouldn't return anything useful for constants. what are you planning to do? ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString
Em qui 20 fev 2014, às 19:56:42, Oswald Buddenhagen escreveu: what are you planning to do? This is the first step: remove setSharable so we have one fewer state to check during ref up down. Keeping isSharedWith is no problem, as it doesn't affect the refcounting. The second step will be to use null d-pointers to indicate static data. That means Q{String,ByteArray}Literal() and Q{String,ByteArray,Vector}::fromRawData() don't have to have a d-pointer. For the latter, it has the extra benefit that fromRawData() won't allocate memory at all. Obviously, if the d-pointer is null, neither the pointer to the data nor the size can be inside the d pointer. That means we have to extract the begin and size from inside the d-pointer and move to the actual class. Fortunately, that's already implemented and very robust. I implemented it close to 3 years ago. https://qt.gitorious.org/qt/thiago-intels-qtbase/commit/8ec07482b2ca9674ee72061c0273e527bc63ad47 https://qt.gitorious.org/qt/thiago-intels-qtbase/commit/3534934f0da0442a75b99fbab0328ce55c26798e That means sizeof(QString) == sizeof(QByteArray)== sizeof(QVector) == 3 * sizeof(void*) I have a corresponding change to grow QVariant to 4 * sizeof(void*) so QStrings can fit. The third step will be to investigate whether Small String Optimisation makes sense. By using the LSB in the d-pointer to indicate whether the SSO is active, we can store: 32-bit 64-bit QString 5 chars 11 chars QByteArray 11 chars23 chars (including the ending null) -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development