[Development] Question about QCoreApplicationData::*_libpaths

Marc Mutz marc.mutz at kdab.com
Mon Jan 18 23:43:37 CET 2016


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.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt Experts



More information about the Development mailing list