[Development] OK to add zero/bulk copy to QVector?

Jiergir Ogoerg f35f22fan at gmail.com
Mon Dec 30 02:58:02 CET 2013


Well, I don't find setBuffer(buf, element_count) ambiguous, at the end
of the day (1) one should read the docs first before using a method
and (2) we can rename it to something that doesn't sound ambiguous.
C++ (and Qt I believe) are about both efficiency and flexibility, the
one I'm proposing (with whatever name is chosen to sound
non-ambiguous) is a bit more efficient and more flexible. Or implement
both (possibly sharing code underneath) and let the user decide which
one to use.

The other question is zero-copy which I'd like it to feature because
it can be quite a win in some cases. I haven't looked at the source
code for QVector so don't know if it can be done technically.

On Mon, Dec 30, 2013 at 3:42 AM, Konstantin Ritt <ritt.ks at gmail.com> wrote:
>>  the 1st one is created automatically when the parent class
> is created which holds the vector, and a second vector is created when
> calling "fromRawData()" when I got the data on the heap to replace
> the vector's buffer.
>
> From the one side, looking to the "QVector(const T *data, int size)" API,
> one'd say QVector copies the data so that the original data could be freed
> (because we do that everywhere else, look i.e. QString, QByteArray,
> etc.)...surprise;
> From the other side, creating a null QVector() (by using a default ctor) is
> no-alloc operation and costs you near to nothing (note Qt containers use the
> power of COW). "QVector<T> data = QVector<T>::fromRawData(dataPtr,
> dataSize)" costs you near to nothing once again but has a pretty nice,
> non-ambiguous "fromRawData" name.
>
> Regards,
> Konstantin
>
>
> 2013/12/30 Jiergir Ogoerg <f35f22fan at gmail.com>
>>
>> I would vouch for a non static method in addition or instead of
>> "static ...fromRawData(..)", because a non-static method
>> allows to set the buffer of a vector (needless to mention - with a
>> zero copy) at any time, not just at vector creation, otherwise,
>> as noted in my previous example, I'd end up having to create two
>> vectors - the 1st one is created automatically when the parent class
>> is created which holds the vector, and a second vector is created when
>> calling "fromRawData()" when I got the data on the heap to replace
>> the vector's buffer.
>> It's not a big deal, but I find it slightly better because it avoids a
>> vector creation as in my case, and you can replace the buffer at any
>> time
>> it suits you.
>>
>>
>> On Mon, Dec 30, 2013 at 2:45 AM, Konstantin Ritt <ritt.ks at gmail.com>
>> wrote:
>> >
>> > There is a plan to add  "static QVector<T> QVector::fromRawData(const T
>> > *data, int size)". Though, I'm not sure if we can do this until 6.0.
>> >
>> > Regards,
>> > Konstantin
>> >
>> >
>> > 2013/12/30 Jiergir Ogoerg <f35f22fan at gmail.com>
>> >>
>> >> QVector is created before I can load the array on the heap, so I can't
>> >> init it to the desired
>> >> item count.
>> >> Particularly I'm talking about QVector<QComposeTableElement>
>> >> m_composeTable
>> >> from
>> >>
>> >>
>> >> qt5/qtbase/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
>> >>
>> >> And because of that I have to (can) resize() it, and resizing sucks
>> >> because it not just creates
>> >> more space for the internal buffer but also initializes each item to
>> >> the default value.
>> >>
>> >> The other option to resize() is reserve, but it doesn't also increase
>> >> the item count of the vector so
>> >> I still have to go over each element and push_back().
>> >>
>> >> Just setting the whole thing with one qvector->setBuffer(array) would
>> >> be quicker and faster.
>> >>
>> >> The example:
>> >> The actual source code is attached (as zip file) in the file
>> >> qtablegenerator.cpp, at static function loadCache(..),
>> >> the quickest approach I could figure out was to use reserve() and then
>> >> push_back() on each item,
>> >> which still does lots of copies:
>> >>
>> >> QComposeTableElement *elem;
>> >>     vec->reserve(kElemCount);
>> >>
>> >>     for(int i=0; i<kElemCount; i++) {
>> >>         elem = (QComposeTableElement*) (buf + (i * kElemSize));
>> >>         vec->push_back(*elem);
>> >>     }
>> >>
>> >>
>> >>
>> >>
>> >> On Sun, Dec 29, 2013 at 11:44 PM, Yves Bailly <yves.bailly at laposte.net>
>> >> wrote:
>> >> > On 29/12/2013 20:10, Jiergir Ogoerg wrote:
>> >> >> Hi,
>> >> >> there are 2 simple options to speed up setting/adding elements to a
>> >> >> vector when a heap buffer is filled in in advance:
>> >> >> 1) Bulk copy.
>> >> >> Assign a bunch of elements at once (from another vector or array),
>> >> >> like std::vector::assign() does.
>> >> >> A big extra copy happens, but avoids multiple calls to push_back().
>> >> >
>> >> > What about this, re-using your example:
>> >> > my_struct *arr = new my_struct[count];
>> >> > QVector<my_struct> v(count);
>> >> > memcpy(v.data(), arr, sizeof(my_struct)*count);
>> >> >
>> >> > Assuming "my_struct" doesn't contain self-referencing references or
>> >> > virtual table.
>> >> >
>> >> > Regards,
>> >> >
>> >> > --
>> >> > (o< | Yves Bailly                          | -o)
>> >> > //\ | Linux Dijon  : http://www.coagul.org | //\
>> >> > \_/ |                                      | \_/`
>> >> > _______________________________________________
>> >> > Development mailing list
>> >> > Development at qt-project.org
>> >> > http://lists.qt-project.org/mailman/listinfo/development
>> >>
>> >> _______________________________________________
>> >> Development mailing list
>> >> Development at qt-project.org
>> >> http://lists.qt-project.org/mailman/listinfo/development
>> >>
>> >
>> >
>> > _______________________________________________
>> > Development mailing list
>> > Development at qt-project.org
>> > http://lists.qt-project.org/mailman/listinfo/development
>> >
>> _______________________________________________
>> Development mailing list
>> Development at qt-project.org
>> http://lists.qt-project.org/mailman/listinfo/development
>
>
>
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
>



More information about the Development mailing list