On Monday 18 January 2016 18:47:42 Matthew Woehlke wrote: > Not really. There is a huge difference between a relocatable type (many, > if not most), and a trivially copyable type (a lot fewer). Operations > such as growing the buffer can be vastly more expensive if the item type > is not relocatable vs. if it is. However, C++ itself currently does not > provide any support for relocation. > > I want to say e.g. std::string is relocatable, but it is certainly not > trivially copyable. Now, imagine a std::vector<std::string> where both > the vector and strings are very large. When the vector needs to resize, > it will have to do a deep copy of ever single item, allocating and > freeing lots of memory in the process. Compare to QVector<std::string> > (assume Q_DECLARE_TYPEINFO declares std::string relocatable), which... > will do a realloc(). Worst case, that's 1 alloc, 1 free, and 1 block > copy... and 0 ctor/dtor calls. > > That's a significant difference. > > (Even using QString instead of std::string does not help much... the > QVector still just does a realloc, while std::vector must perform 2*N > atomic operations.)
a) std::string is not a movable type (at least I get a heap corruption when marking it as such in GCC 5.3) b) #include <QVector> #include <string> int main() { QVector<std::string> l; int oldC = l.capacity(); for (int i = 0; i < 10000000; ++i) { char buf[std::numeric_limits<int>::digits + 1]; sprintf(buf, "%d", i); l.push_back(buf); int newC = l.capacity(); if (newC != oldC) qDebug("%d", newC); oldC = newC; } } $ time ./test <snip> real 0m1.598s user 0m1.400s sys 0m0.192s #include <QVector> #include <string> int main() { std::vector<std::string> l; int oldC = l.capacity(); for (int i = 0; i < 10000000; ++i) { char buf[std::numeric_limits<int>::digits + 1]; sprintf(buf, "%d", i); l.push_back(buf); int newC = l.capacity(); if (newC != oldC) qDebug("%d", newC); oldC = newC; } } $ time ./test <snip> real 0m1.481s user 0m1.264s sys 0m0.212s #include <QVector> #include <string> int main() { QVector<QByteArray> l; int oldC = l.capacity(); for (int i = 0; i < 10000000; ++i) { char buf[std::numeric_limits<int>::digits + 1]; sprintf(buf, "%d", i); l.push_back(buf); int newC = l.capacity(); if (newC != oldC) qDebug("%d", newC); oldC = newC; } } $ time ./test <snip> real 0m1.769s user 0m1.572s sys 0m0.192s best of three runs, core i7-2720QM, GCC 5.3 HTH, Marc -- Marc Mutz <marc.m...@kdab.com> | Senior Software Engineer KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company Tel: +49-30-521325470 KDAB - The Qt Experts _______________________________________________ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development