doc: Corrected docs for QList and QVector
The docs for QList advised users to choose QList over QVector for efficiency reasons. The advise should be to use QVector over QList for efficiency reasons. This update corrects that misunderstanding. Change-Id: Ie04c99ab7fe6aef4bd1d39175c9564455b0122de Task-number: QTBUG-47196 Reviewed-by: Topi Reiniö <topi.reinio@digia.com> Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
parent
c067c012dc
commit
02c906acc3
@ -65,4 +65,13 @@
|
|||||||
\externalpage http://doc-snapshot.qt-project.org/qt5-5.4/designer-widget-mode.html#the-property-editor
|
\externalpage http://doc-snapshot.qt-project.org/qt5-5.4/designer-widget-mode.html#the-property-editor
|
||||||
\title Qt Designer's Widget Editing Mode#The Property Editor
|
\title Qt Designer's Widget Editing Mode#The Property Editor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\externalpage http://marcmutz.wordpress.com/effective-qt/containers/#containers-qlist
|
||||||
|
\title Pros and Cons of Using QList
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\externalpage http://marcmutz.wordpress.com/effective-qt/containers/
|
||||||
|
\title Understand the Qt Containers
|
||||||
*/
|
*/
|
||||||
|
@ -332,41 +332,56 @@ void **QListData::erase(void **xi)
|
|||||||
\reentrant
|
\reentrant
|
||||||
|
|
||||||
QList\<T\> is one of Qt's generic \l{container classes}. It
|
QList\<T\> is one of Qt's generic \l{container classes}. It
|
||||||
stores a list of values and provides fast index-based access as
|
stores items in a list that provides fast index-based access
|
||||||
well as fast insertions and removals.
|
and index-based insertions and removals.
|
||||||
|
|
||||||
QList\<T\>, QLinkedList\<T\>, and QVector\<T\> provide similar
|
QList\<T\>, QLinkedList\<T\>, and QVector\<T\> provide similar
|
||||||
functionality. Here's an overview:
|
APIs and functionality. They are often interchangeable, but there
|
||||||
|
are performance consequences. Here is an overview of use cases:
|
||||||
|
|
||||||
\list
|
\list
|
||||||
\li For most purposes, QList is the right class to use. Its
|
\li QVector should be your default first choice.
|
||||||
index-based API is more convenient than QLinkedList's
|
QVector\<T\> will usually give better performance than QList\<T\>,
|
||||||
iterator-based API, and it is usually faster than
|
because QVector\<T\> always stores its items sequentially in memory,
|
||||||
QVector because of the way it stores its items in
|
where QList\<T\> will allocate its items on the heap unless
|
||||||
memory. It also expands to less code in your executable.
|
\c {sizeof(T) <= sizeof(void*)} and T has been declared to be
|
||||||
\li If you need a real linked list, with guarantees of \l{constant
|
either a \c{Q_MOVABLE_TYPE} or a \c{Q_PRIMITIVE_TYPE} using
|
||||||
time} insertions in the middle of the list and iterators to
|
\l {Q_DECLARE_TYPEINFO}. See the \l {Pros and Cons of Using QList}
|
||||||
items rather than indexes, use QLinkedList.
|
for an explanation.
|
||||||
\li If you want the items to occupy adjacent memory positions,
|
\li However, QList is used throughout the Qt APIs for passing
|
||||||
use QVector.
|
parameters and for returning values. Use QList to interface with
|
||||||
|
those APIs.
|
||||||
|
\li If you need a real linked list, which guarantees
|
||||||
|
\l {Algorithmic Complexity}{constant time} insertions mid-list and
|
||||||
|
uses iterators to items rather than indexes, use QLinkedList.
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
|
\note QVector and QVarLengthArray both guarantee C-compatible
|
||||||
|
array layout. QList does not. This might be important if your
|
||||||
|
application must interface with a C API.
|
||||||
|
|
||||||
Internally, QList\<T\> is represented as an array of pointers to
|
\note Iterators into a QLinkedList and references into
|
||||||
items of type T. If T is itself a pointer type or a basic type
|
heap-allocating QLists remain valid long as the referenced items
|
||||||
that is no larger than a pointer, or if T is one of Qt's \l{shared
|
remain in the container. This is not true for iterators and
|
||||||
classes}, then QList\<T\> stores the items directly in the pointer
|
references into a QVector and non-heap-allocating QLists.
|
||||||
array. For lists under a thousand items, this array representation
|
|
||||||
allows for very fast insertions in the middle, and it allows
|
Internally, QList\<T\> is represented as an array of T if
|
||||||
index-based access. Furthermore, operations like prepend() and
|
If \c{sizeof(T) <= sizeof(void*)} and T has been declared to be
|
||||||
append() are very fast, because QList preallocates memory at both
|
either a \c{Q_MOVABLE_TYPE} or a \c{Q_PRIMITIVE_TYPE} using
|
||||||
|
\l {Q_DECLARE_TYPEINFO}. Otherwise, QList\<T\> is represented
|
||||||
|
as an array of T* and the items are allocated on the heap.
|
||||||
|
|
||||||
|
The array representation allows very fast insertions and
|
||||||
|
index-based access. The prepend() and append() operations are
|
||||||
|
also very fast because QList preallocates memory at both
|
||||||
ends of its internal array. (See \l{Algorithmic Complexity} for
|
ends of its internal array. (See \l{Algorithmic Complexity} for
|
||||||
details.) Note, however, that for unshared list items that are
|
details.
|
||||||
larger than a pointer, each append or insert of a new item
|
|
||||||
requires allocating the new item on the heap, and this per item
|
Note, however, that when the conditions specified above are not met,
|
||||||
allocation might make QVector a better choice in cases that do
|
each append or insert of a new item requires allocating the new item
|
||||||
lots of appending or inserting, since QVector allocates memory for
|
on the heap, and this per item allocation will make QVector a better
|
||||||
its items in a single heap allocation.
|
choice for use cases that do a lot of appending or inserting, because
|
||||||
|
QVector can allocate memory for many items in a single heap allocation.
|
||||||
|
|
||||||
Note that the internal array only ever gets bigger over the life
|
Note that the internal array only ever gets bigger over the life
|
||||||
of the list. It never shrinks. The internal array is deallocated
|
of the list. It never shrinks. The internal array is deallocated
|
||||||
@ -401,9 +416,10 @@ void **QListData::erase(void **xi)
|
|||||||
|
|
||||||
\snippet code/src_corelib_tools_qlistdata.cpp 2
|
\snippet code/src_corelib_tools_qlistdata.cpp 2
|
||||||
|
|
||||||
Because QList is implemented as an array of pointers, this
|
Because QList is implemented as an array of pointers for types
|
||||||
operation is very fast (\l{constant time}). For read-only access,
|
that are larger than a pointer or are not movable, this operation
|
||||||
an alternative syntax is to use at():
|
requires (\l{Algorithmic Complexity}{constant time}). For read-only
|
||||||
|
access, an alternative syntax is to use at():
|
||||||
|
|
||||||
\snippet code/src_corelib_tools_qlistdata.cpp 3
|
\snippet code/src_corelib_tools_qlistdata.cpp 3
|
||||||
|
|
||||||
@ -417,10 +433,10 @@ void **QListData::erase(void **xi)
|
|||||||
|
|
||||||
\snippet code/src_corelib_tools_qlistdata.cpp 4
|
\snippet code/src_corelib_tools_qlistdata.cpp 4
|
||||||
|
|
||||||
Inserting and removing items at either ends of the list is very
|
Inserting and removing items at either end of the list is very
|
||||||
fast (\l{constant time} in most cases), because QList
|
fast (\l{Algorithmic Complexity}{constant time} in most cases),
|
||||||
preallocates extra space on both sides of its internal buffer to
|
because QList preallocates extra space on both sides of its
|
||||||
allow for fast growth at both ends of the list.
|
internal buffer to allow for fast growth at both ends of the list.
|
||||||
|
|
||||||
If you want to find all occurrences of a particular value in a
|
If you want to find all occurrences of a particular value in a
|
||||||
list, use indexOf() or lastIndexOf(). The former searches forward
|
list, use indexOf() or lastIndexOf(). The former searches forward
|
||||||
@ -481,6 +497,11 @@ void **QListData::erase(void **xi)
|
|||||||
\l{QStringList::removeDuplicates()}{removeDuplicates},
|
\l{QStringList::removeDuplicates()}{removeDuplicates},
|
||||||
\l{QStringList::sort()}{sort}.
|
\l{QStringList::sort()}{sort}.
|
||||||
|
|
||||||
|
\section1 More Information on Using Qt Containers
|
||||||
|
|
||||||
|
For a detailed discussion comparing Qt containers with each other and
|
||||||
|
with STL containers, see \l {Understand the Qt Containers}.
|
||||||
|
|
||||||
\sa QListIterator, QMutableListIterator, QLinkedList, QVector
|
\sa QListIterator, QMutableListIterator, QLinkedList, QVector
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -512,10 +533,11 @@ void **QListData::erase(void **xi)
|
|||||||
|
|
||||||
Constructs a copy of \a other.
|
Constructs a copy of \a other.
|
||||||
|
|
||||||
This operation takes \l{constant time}, because QList is
|
This operation takes \l{Algorithmic Complexity}{constant time},
|
||||||
\l{implicitly shared}. This makes returning a QList from a
|
because QList is \l{implicitly shared}. This makes returning a
|
||||||
function very fast. If a shared instance is modified, it will be
|
QList from a function very fast. If a shared instance is modified,
|
||||||
copied (copy-on-write), and that takes \l{linear time}.
|
it will be copied (copy-on-write), and that takes
|
||||||
|
\l{Algorithmic Complexity}{linear time}.
|
||||||
|
|
||||||
\sa operator=()
|
\sa operator=()
|
||||||
*/
|
*/
|
||||||
@ -700,7 +722,7 @@ void **QListData::erase(void **xi)
|
|||||||
Returns the item at index position \a i in the list. \a i must be
|
Returns the item at index position \a i in the list. \a i must be
|
||||||
a valid index position in the list (i.e., 0 <= \a i < size()).
|
a valid index position in the list (i.e., 0 <= \a i < size()).
|
||||||
|
|
||||||
This function is very fast (\l{constant time}).
|
This function is very fast (\l{Algorithmic Complexity}{constant time}).
|
||||||
|
|
||||||
\sa value(), operator[]()
|
\sa value(), operator[]()
|
||||||
*/
|
*/
|
||||||
@ -713,8 +735,8 @@ void **QListData::erase(void **xi)
|
|||||||
|
|
||||||
If this function is called on a list that is currently being shared, it
|
If this function is called on a list that is currently being shared, it
|
||||||
will trigger a copy of all elements. Otherwise, this function runs in
|
will trigger a copy of all elements. Otherwise, this function runs in
|
||||||
\l{constant time}. If you do not want to modify the list you should use
|
\l{Algorithmic Complexity}{constant time}. If you do not want to modify
|
||||||
QList::at().
|
the list you should use QList::at().
|
||||||
|
|
||||||
\sa at(), value()
|
\sa at(), value()
|
||||||
*/
|
*/
|
||||||
@ -723,7 +745,7 @@ void **QListData::erase(void **xi)
|
|||||||
|
|
||||||
\overload
|
\overload
|
||||||
|
|
||||||
Same as at(). This function runs in \l{constant time}.
|
Same as at(). This function runs in \l{Algorithmic Complexity}{constant time}.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \fn QList::reserve(int alloc)
|
/*! \fn QList::reserve(int alloc)
|
||||||
@ -749,9 +771,9 @@ void **QListData::erase(void **xi)
|
|||||||
This is the same as list.insert(size(), \a value).
|
This is the same as list.insert(size(), \a value).
|
||||||
|
|
||||||
If this list is not shared, this operation is typically
|
If this list is not shared, this operation is typically
|
||||||
very fast (amortized \l{constant time}), because QList
|
very fast (amortized \l{Algorithmic Complexity}{constant time}),
|
||||||
preallocates extra space on both sides of its internal
|
because QList preallocates extra space on both sides of its
|
||||||
buffer to allow for fast growth at both ends of the list.
|
internal buffer to allow for fast growth at both ends of the list.
|
||||||
|
|
||||||
\sa operator<<(), prepend(), insert()
|
\sa operator<<(), prepend(), insert()
|
||||||
*/
|
*/
|
||||||
@ -777,9 +799,9 @@ void **QListData::erase(void **xi)
|
|||||||
This is the same as list.insert(0, \a value).
|
This is the same as list.insert(0, \a value).
|
||||||
|
|
||||||
If this list is not shared, this operation is typically
|
If this list is not shared, this operation is typically
|
||||||
very fast (amortized \l{constant time}), because QList
|
very fast (amortized \l{Algorithmic Complexity}{constant time}),
|
||||||
preallocates extra space on both sides of its internal
|
because QList preallocates extra space on both sides of its
|
||||||
buffer to allow for fast growth at both ends of the list.
|
internal buffer to allow for fast growth at both ends of the list.
|
||||||
|
|
||||||
\sa append(), insert()
|
\sa append(), insert()
|
||||||
*/
|
*/
|
||||||
@ -870,7 +892,8 @@ void **QListData::erase(void **xi)
|
|||||||
same as takeAt(0). This function assumes the list is not empty. To
|
same as takeAt(0). This function assumes the list is not empty. To
|
||||||
avoid failure, call isEmpty() before calling this function.
|
avoid failure, call isEmpty() before calling this function.
|
||||||
|
|
||||||
If this list is not shared, this operation takes \l{constant time}.
|
If this list is not shared, this operation takes
|
||||||
|
\l {Algorithmic Complexity}{constant time}.
|
||||||
|
|
||||||
If you don't use the return value, removeFirst() is more
|
If you don't use the return value, removeFirst() is more
|
||||||
efficient.
|
efficient.
|
||||||
@ -885,7 +908,8 @@ void **QListData::erase(void **xi)
|
|||||||
not empty. To avoid failure, call isEmpty() before calling this
|
not empty. To avoid failure, call isEmpty() before calling this
|
||||||
function.
|
function.
|
||||||
|
|
||||||
If this list is not shared, this operation takes \l{constant time}.
|
If this list is not shared, this operation takes
|
||||||
|
\l {Algorithmic Complexity}{constant time}.
|
||||||
|
|
||||||
If you don't use the return value, removeLast() is more
|
If you don't use the return value, removeLast() is more
|
||||||
efficient.
|
efficient.
|
||||||
|
@ -45,34 +45,42 @@
|
|||||||
stores its items in adjacent memory locations and provides fast
|
stores its items in adjacent memory locations and provides fast
|
||||||
index-based access.
|
index-based access.
|
||||||
|
|
||||||
QList\<T\>, QLinkedList\<T\>, and QVarLengthArray\<T\> provide
|
QList\<T\>, QLinkedList\<T\>, QVector\<T\>, and QVarLengthArray\<T\>
|
||||||
similar functionality. Here's an overview:
|
provide similar APIs and functionality. They are often interchangeable,
|
||||||
|
but there are performance consequences. Here is an overview of use cases:
|
||||||
|
|
||||||
\list
|
\list
|
||||||
\li For most purposes, QList is the right class to use. Operations
|
\li QVector should be your default first choice.
|
||||||
like prepend() and insert() are usually faster than with
|
QVector\<T\> will usually give better performance than QList\<T\>,
|
||||||
QVector because of the way QList stores its items in memory
|
because QVector\<T\> always stores its items sequentially in memory,
|
||||||
(see \l{Algorithmic Complexity} for details),
|
where QList\<T\> will allocate its items on the heap unless
|
||||||
and its index-based API is more convenient than QLinkedList's
|
\c {sizeof(T) <= sizeof(void*)} and T has been declared to be
|
||||||
iterator-based API. It also expands to less code in your
|
either a \c{Q_MOVABLE_TYPE} or a \c{Q_PRIMITIVE_TYPE} using
|
||||||
executable.
|
\l {Q_DECLARE_TYPEINFO}. See the \l {Pros and Cons of Using QList}
|
||||||
\li If you need a real linked list, with guarantees of \l{constant
|
for an explanation.
|
||||||
time} insertions in the middle of the list and iterators to
|
\li However, QList is used throughout the Qt APIs for passing
|
||||||
items rather than indexes, use QLinkedList.
|
parameters and for returning values. Use QList to interface with
|
||||||
\li If you want the items to occupy adjacent memory positions, or
|
those APIs.
|
||||||
if your items are larger than a pointer and you want to avoid
|
\li If you need a real linked list, which guarantees
|
||||||
the overhead of allocating them on the heap individually at
|
\l{Algorithmic Complexity}{constant time} insertions mid-list and
|
||||||
insertion time, then use QVector.
|
uses iterators to items rather than indexes, use QLinkedList.
|
||||||
\li If you want a low-level variable-size array, QVarLengthArray
|
|
||||||
may be sufficient.
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
|
\note QVector and QVarLengthArray both guarantee C-compatible
|
||||||
|
array layout. QList does not. This might be important if your
|
||||||
|
application must interface with a C API.
|
||||||
|
|
||||||
|
\note Iterators into a QLinkedList and references into
|
||||||
|
heap-allocating QLists remain valid long as the referenced items
|
||||||
|
remain in the container. This is not true for iterators and
|
||||||
|
references into a QVector and non-heap-allocating QLists.
|
||||||
|
|
||||||
Here's an example of a QVector that stores integers and a QVector
|
Here's an example of a QVector that stores integers and a QVector
|
||||||
that stores QString values:
|
that stores QString values:
|
||||||
|
|
||||||
\snippet code/src_corelib_tools_qvector.cpp 0
|
\snippet code/src_corelib_tools_qvector.cpp 0
|
||||||
|
|
||||||
QVector stores a vector (or array) of items. Typically, vectors
|
QVector stores its items in a vector (array). Typically, vectors
|
||||||
are created with an initial size. For example, the following code
|
are created with an initial size. For example, the following code
|
||||||
constructs a QVector with 200 elements:
|
constructs a QVector with 200 elements:
|
||||||
|
|
||||||
@ -166,6 +174,11 @@
|
|||||||
with references to its own values. Doing so will cause your application to
|
with references to its own values. Doing so will cause your application to
|
||||||
abort with an error message.
|
abort with an error message.
|
||||||
|
|
||||||
|
\section2 More Information on Using Qt Containers
|
||||||
|
|
||||||
|
For a detailed discussion comparing Qt containers with each other and
|
||||||
|
with STL containers, see \l {Understand the Qt Containers}.
|
||||||
|
|
||||||
\sa QVectorIterator, QMutableVectorIterator, QList, QLinkedList
|
\sa QVectorIterator, QMutableVectorIterator, QList, QLinkedList
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -218,10 +231,11 @@
|
|||||||
|
|
||||||
Constructs a copy of \a other.
|
Constructs a copy of \a other.
|
||||||
|
|
||||||
This operation takes \l{constant time}, because QVector is
|
This operation takes \l{Algorithmic Complexity}{constant time},
|
||||||
\l{implicitly shared}. This makes returning a QVector from a
|
because QVector is \l{implicitly shared}. This makes returning
|
||||||
function very fast. If a shared instance is modified, it will be
|
a QVector from a function very fast. If a shared instance is
|
||||||
copied (copy-on-write), and that takes \l{linear time}.
|
modified, it will be copied (copy-on-write), and that takes
|
||||||
|
\l{Algorithmic Complexity}{linear time}.
|
||||||
|
|
||||||
\sa operator=()
|
\sa operator=()
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user