QVector: preserve capacity in clear()
This is what std::vector implementations usually do, because it minimizes memory fragmentation and useless allocations since no user will call clear() unless she intends to append new data afterwards. Fix calls to resize(0) that show how existing code tried to work around the issue. Adjust test. Port from QVERIFY(==) to QCOMPARE as a drive-by. [ChangeLog][QtCore][QVector] clear() now preserves capacity. To shed capacity, call squeeze() or swap with a default-constructed QVector object, see the documentation for an example. Change-Id: I9cebe611a97e027a89e821e64408a4741b31f1f6 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
This commit is contained in:
parent
85c2a128ef
commit
a7885c9756
@ -286,7 +286,7 @@ void QEventDispatcherUNIXPrivate::markPendingSocketNotifiers()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pollfds.resize(0);
|
pollfds.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int QEventDispatcherUNIXPrivate::activateSocketNotifiers()
|
int QEventDispatcherUNIXPrivate::activateSocketNotifiers()
|
||||||
@ -480,8 +480,8 @@ bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags)
|
|||||||
if (!canWait || (include_timers && d->timerList.timerWait(wait_tm)))
|
if (!canWait || (include_timers && d->timerList.timerWait(wait_tm)))
|
||||||
tm = &wait_tm;
|
tm = &wait_tm;
|
||||||
|
|
||||||
|
d->pollfds.clear();
|
||||||
d->pollfds.reserve(1 + (include_notifiers ? d->socketNotifiers.size() : 0));
|
d->pollfds.reserve(1 + (include_notifiers ? d->socketNotifiers.size() : 0));
|
||||||
d->pollfds.resize(0);
|
|
||||||
|
|
||||||
if (include_notifiers)
|
if (include_notifiers)
|
||||||
for (auto it = d->socketNotifiers.cbegin(); it != d->socketNotifiers.cend(); ++it)
|
for (auto it = d->socketNotifiers.cbegin(); it != d->socketNotifiers.cend(); ++it)
|
||||||
|
@ -2335,7 +2335,7 @@ QRegExpCharClass::QRegExpCharClass()
|
|||||||
void QRegExpCharClass::clear()
|
void QRegExpCharClass::clear()
|
||||||
{
|
{
|
||||||
c = 0;
|
c = 0;
|
||||||
r.resize(0);
|
r.clear();
|
||||||
n = false;
|
n = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,8 +502,19 @@
|
|||||||
|
|
||||||
/*! \fn void QVector::clear()
|
/*! \fn void QVector::clear()
|
||||||
|
|
||||||
Removes all the elements from the vector and releases the memory used by
|
Removes all the elements from the vector.
|
||||||
the vector.
|
|
||||||
|
\note Until Qt 5.6, this also released the memory used by
|
||||||
|
the vector. From Qt 5.7, the capacity is preserved. To shed
|
||||||
|
all capacity, swap with a default-constructed vector:
|
||||||
|
\code
|
||||||
|
QVector<T> v ...;
|
||||||
|
QVector<T>().swap(v);
|
||||||
|
Q_ASSERT(v.capacity() == 0);
|
||||||
|
\endcode
|
||||||
|
or call squeeze().
|
||||||
|
|
||||||
|
\sa squeeze()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \fn const T &QVector::at(int i) const
|
/*! \fn const T &QVector::at(int i) const
|
||||||
|
@ -419,7 +419,7 @@ void QVector<T>::resize(int asize)
|
|||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void QVector<T>::clear()
|
inline void QVector<T>::clear()
|
||||||
{ *this = QVector<T>(); }
|
{ resize(0); }
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline const T &QVector<T>::at(int i) const
|
inline const T &QVector<T>::at(int i) const
|
||||||
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::at", "index out of range");
|
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::at", "index out of range");
|
||||||
|
@ -1020,10 +1020,8 @@ bool QXmlStreamReaderPrivate::parse()
|
|||||||
prefix.clear();
|
prefix.clear();
|
||||||
qualifiedName.clear();
|
qualifiedName.clear();
|
||||||
namespaceUri.clear();
|
namespaceUri.clear();
|
||||||
if (publicNamespaceDeclarations.size())
|
|
||||||
publicNamespaceDeclarations.clear();
|
publicNamespaceDeclarations.clear();
|
||||||
if (attributes.size())
|
attributes.clear();
|
||||||
attributes.resize(0);
|
|
||||||
if (isEmptyElement) {
|
if (isEmptyElement) {
|
||||||
setType(QXmlStreamReader::EndElement);
|
setType(QXmlStreamReader::EndElement);
|
||||||
Tag &tag = tagStack_pop();
|
Tag &tag = tagStack_pop();
|
||||||
|
@ -375,7 +375,7 @@ QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e)
|
|||||||
QKeySequence::SequenceMatch result = QKeySequence::NoMatch;
|
QKeySequence::SequenceMatch result = QKeySequence::NoMatch;
|
||||||
|
|
||||||
// We start fresh each time..
|
// We start fresh each time..
|
||||||
d->identicals.resize(0);
|
d->identicals.clear();
|
||||||
|
|
||||||
result = find(e);
|
result = find(e);
|
||||||
if (result == QKeySequence::NoMatch && (e->modifiers() & Qt::KeypadModifier)) {
|
if (result == QKeySequence::NoMatch && (e->modifiers() & Qt::KeypadModifier)) {
|
||||||
@ -448,7 +448,7 @@ QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifier
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Looking for new identicals, scrap old
|
// Looking for new identicals, scrap old
|
||||||
d->identicals.resize(0);
|
d->identicals.clear();
|
||||||
|
|
||||||
bool partialFound = false;
|
bool partialFound = false;
|
||||||
bool identicalDisabledFound = false;
|
bool identicalDisabledFound = false;
|
||||||
|
@ -2166,7 +2166,7 @@ void Parser::init(const QString &css, bool isFile)
|
|||||||
}
|
}
|
||||||
|
|
||||||
hasEscapeSequences = false;
|
hasEscapeSequences = false;
|
||||||
symbols.resize(0);
|
symbols.clear();
|
||||||
symbols.reserve(8);
|
symbols.reserve(8);
|
||||||
Scanner::scan(Scanner::preprocess(styleSheet, &hasEscapeSequences), &symbols);
|
Scanner::scan(Scanner::preprocess(styleSheet, &hasEscapeSequences), &symbols);
|
||||||
index = 0;
|
index = 0;
|
||||||
|
@ -1128,7 +1128,7 @@ void QTextDocumentPrivate::clearUndoRedoStacks(QTextDocument::Stacks stacksToCle
|
|||||||
delete c.custom;
|
delete c.custom;
|
||||||
}
|
}
|
||||||
undoState = 0;
|
undoState = 0;
|
||||||
undoStack.resize(0);
|
undoStack.clear();
|
||||||
if (emitSignals && undoCommandsAvailable)
|
if (emitSignals && undoCommandsAvailable)
|
||||||
emitUndoAvailable(false);
|
emitUndoAvailable(false);
|
||||||
if (emitSignals && redoCommandsAvailable)
|
if (emitSignals && redoCommandsAvailable)
|
||||||
|
@ -516,7 +516,7 @@ QVector<QRect> MinOverlapPlacer::findMaxOverlappers(const QRect &domain, const Q
|
|||||||
if (overlap >= maxOverlap || maxOverlap == -1) {
|
if (overlap >= maxOverlap || maxOverlap == -1) {
|
||||||
if (overlap > maxOverlap) {
|
if (overlap > maxOverlap) {
|
||||||
maxOverlap = overlap;
|
maxOverlap = overlap;
|
||||||
result.resize(0);
|
result.clear();
|
||||||
}
|
}
|
||||||
result << srcRect;
|
result << srcRect;
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ void QMenuBarPrivate::updateGeometries()
|
|||||||
if(itemsDirty) {
|
if(itemsDirty) {
|
||||||
for(int j = 0; j < shortcutIndexMap.size(); ++j)
|
for(int j = 0; j < shortcutIndexMap.size(); ++j)
|
||||||
q->releaseShortcut(shortcutIndexMap.value(j));
|
q->releaseShortcut(shortcutIndexMap.value(j));
|
||||||
shortcutIndexMap.resize(0); // faster than clear
|
shortcutIndexMap.clear();
|
||||||
const int actionsCount = actions.count();
|
const int actionsCount = actions.count();
|
||||||
shortcutIndexMap.reserve(actionsCount);
|
shortcutIndexMap.reserve(actionsCount);
|
||||||
for (int i = 0; i < actionsCount; i++)
|
for (int i = 0; i < actionsCount; i++)
|
||||||
|
@ -1141,7 +1141,7 @@ void QTextBrowser::clearHistory()
|
|||||||
d->forwardStack.clear();
|
d->forwardStack.clear();
|
||||||
if (!d->stack.isEmpty()) {
|
if (!d->stack.isEmpty()) {
|
||||||
QTextBrowserPrivate::HistoryEntry historyEntry = d->stack.top();
|
QTextBrowserPrivate::HistoryEntry historyEntry = d->stack.top();
|
||||||
d->stack.resize(0);
|
d->stack.clear();
|
||||||
d->stack.push(historyEntry);
|
d->stack.push(historyEntry);
|
||||||
d->home = historyEntry.url;
|
d->home = historyEntry.url;
|
||||||
}
|
}
|
||||||
|
@ -734,10 +734,11 @@ void tst_QVector::clear() const
|
|||||||
QVector<T> myvec;
|
QVector<T> myvec;
|
||||||
myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
|
myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
|
||||||
|
|
||||||
QVERIFY(myvec.size() == 3);
|
const auto oldCapacity = myvec.capacity();
|
||||||
|
QCOMPARE(myvec.size(), 3);
|
||||||
myvec.clear();
|
myvec.clear();
|
||||||
QVERIFY(myvec.size() == 0);
|
QCOMPARE(myvec.size(), 0);
|
||||||
QVERIFY(myvec.capacity() == 0);
|
QCOMPARE(myvec.capacity(), oldCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QVector::clearInt() const
|
void tst_QVector::clearInt() const
|
||||||
@ -1945,7 +1946,7 @@ void tst_QVector::resizePOD() const
|
|||||||
|
|
||||||
const int capacity = vector.capacity();
|
const int capacity = vector.capacity();
|
||||||
|
|
||||||
vector.resize(0);
|
vector.clear();
|
||||||
QCOMPARE(vector.size(), 0);
|
QCOMPARE(vector.size(), 0);
|
||||||
QVERIFY(vector.capacity() <= capacity);
|
QVERIFY(vector.capacity() <= capacity);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user