> On Feb. 15, 2014, 8:28 p.m., David Faure wrote: > > Yeah the description is wrong. Making something Q_MOVABLE means that > > inserting into the list, or the copying that happens when reallocating for > > more space, will be able to memmove() instead of copy-constructing items. > > This doesn't change the actual memory layout (which only depends on the > > size of the items). > > > > Basically, as long as UDSEntry doesn't have a "q" pointer in its private > > class (which it doesn't), it's movable. So marking it as movable is > > correct, but not with this commit message. > > > > As to a difference in performance, I would be surprised if it was > > measurable. The copy ctor for UDSEntry plays with a refcount. > > Frank Reininghaus wrote: > "Yeah the description is wrong. Making something Q_MOVABLE means that > inserting into the list, or the copying that happens when reallocating for > more space, will be able to memmove() instead of copy-constructing items. > This doesn't change the actual memory layout (which only depends on the size > of the items)" > > I am afraid this is wrong. A QList<T> is essentially a small wrapper > around a QList<void*>, which *always* uses memmove() to move around its > items. If sizeof(T) <= sizeof(void*), and it's known that using memmove() is > safe for T (e.g. because it's POD or Qt itself declares it as Q_MOVABLE), > then QList just reinterprets each void* as an item of type T. > > If that is not the case, then QList<T> will effectively become a > QList<T*>, and allocate memory for each item individually on the heap. > > So yes, making something Q_MOVABLE definitely changes the actual memory > layout. > > Anyone who does not believe me is encouraged to have a quick look at > these excellent posts by Marc Mutz: > > > http://marcmutz.wordpress.com/2010/07/29/sneak-preview-qlist-considered-harmful/ > > http://marcmutz.wordpress.com/effective-qt/containers/ > > or look at the source, > > http://code.woboq.org/qt5/qtbase/src/corelib/tools/qlist.h.html > > Note that void QList<T>::append(const T &t) calls the function > > void QList<T>::node_construct(Node *n, const T &t) > > which does > > n->v = new T(t) > > if QTypeInfo<T>::isLarge (which means that T is larger than a void*) or > QTypeInfo<T>::isStatic (which means that T has not been declared as > Q_MOVABLE). This is all explained in Marc's second post. > > > "As to a difference in performance, I would be surprised if it was > measurable. The copy ctor for UDSEntry plays with a refcount." > > My point is *not* that this change saves us the refcount updates when > items are moved around. > > What is saves is that a small block (including the overhead that the > memory allocator adds to each allocatin, usually 32 bytes) of memory is > allocated/deallocated every time an item is added to/removed from the list. > > This might still not affect the performance noticeably in many cases, but > allocating memory is a lot more expensive than just increasing a refcount.
You are right. Sorry, I was confusing with QVector. - David ----------------------------------------------------------- This is an automatically generated e-mail. To reply, visit: https://git.reviewboard.kde.org/r/115739/#review49873 ----------------------------------------------------------- On Feb. 13, 2014, 8:23 p.m., Frank Reininghaus wrote: > > ----------------------------------------------------------- > This is an automatically generated e-mail. To reply, visit: > https://git.reviewboard.kde.org/r/115739/ > ----------------------------------------------------------- > > (Updated Feb. 13, 2014, 8:23 p.m.) > > > Review request for KDE Frameworks and David Faure. > > > Repository: kio > > > Description > ------- > > I'm continuing my efforts to make UDSEntry more efficient, which were started > in https://git.reviewboard.kde.org/r/113591/. This is the second step, and > I'll probably do more in the future, for which I will split > https://git.reviewboard.kde.org/r/113355/ into independent parts. > > This patch contains the following changes (which are separate commits): > > 1. Make UDSEntry a Q_MOVABLE type. This has the effect that a QList<UDSEntry> > a.k.a. UDSEntryList will store the actual entries in a single allocated block > of memory, and not pointers to UDSEntries which are allocated individually on > the heap (this means that this change is binary incompatible). This reduces > the memory usage by 32 bytes per UDSEntry in a QList because each memory > allocation uses at least 32 bytes on a 64-bit system. > > This idea is similar to what I proposed for KFileItem in > https://git.reviewboard.kde.org/r/111789/. That one had to be reverted later > though because it turned out that KDirLister does rely on QList<KFileItem> > storing only pointers to the KFileItems. I'm confident that no such trouble > will happen for UDSEntry - all KIO unit tests still pass. > > One could argue that we could simply use a UDSEntryVector instead of a > UDSEntyList to achieve the same memory savings, but considering that the list > is used quite frequently ( http://lxr.kde.org/ident?i=UDSEntryList ), this > might require a lot of porting work and cause other unexpected problems. > > Note that I could not make the Q_DECLARE_TYPEINFO declaration work if it was > inside the KIO namespace, but I still preferred to do it immediately after > the class declaration, so I had to interrupt the namespace briefly. > > 2. Add some benchmarks to measure how long typical UDSEntry operations take: > add fields to an entry, read fields from an entry, store a UDSEntryList in a > QByteArray, and read it back from the QByteArray. > > All measurements are done both for UDSEntries with 8 fields (this is a rather > typical use case because kio_file usually creates 8 fields), and for entries > with the maximum number of fields. > > 3. Add a simple manual test ('listjobtest') that runs a KIO::ListJob for a > given URL. This can be used to easily measure the memory usage of the > UDSEntryList that contains an entry for each file at that URL. > > > Diffs > ----- > > src/core/udsentry.h 9550a7e > tests/CMakeLists.txt dbca6a5 > tests/listjobtest.cpp PRE-CREATION > tests/udsentrybenchmark.cpp PRE-CREATION > > Diff: https://git.reviewboard.kde.org/r/115739/diff/ > > > Testing > ------- > > 1. KIO unit tests still pass. > > 2. I've confirmed with the new 'listjobtest' and KSysGuard that the memory > usage is really lowered by 32 bytes per item in a UDSEntryList. > > 3. The benchmark results do not change significantly. I only tested it with a > debug build (i.e., with optimizations disabled) though, and I'm afraid I > might be lacking the resources to set up an additional build of Qt5 and all > of KF5 in release mode. However, since UDSEntry essentially only depends on > qtbase, I might be able to just do a release build of qtbase and build a > stand-alone version of UDSEntry+benchmarks on top of that. I'll look into > this option for getting reliable benchmark results when I work on further > improvements in the future. > > > Thanks, > > Frank Reininghaus > >
_______________________________________________ Kde-frameworks-devel mailing list Kde-frameworks-devel@kde.org https://mail.kde.org/mailman/listinfo/kde-frameworks-devel