Analyze Of QByteArray
After two days’ programming, I find some problem. With the code became larger and larger, I am getting slower and slower program. So I have to find the reason.
In my program, I often use the QByteArray class. So it will be my sally port. Today I will analyze the mechanism of QByteArray.
The QByteArray class in the file corelib/tools/qbytearray.h.
struct Data {
QBasicAtomicInt ref;
int alloc, size;
// ### Qt 5.0: We need to add the missing capacity bit
// (like other tool classes have), to maintain the
// reserved memory on resize.
char *data;
char array[1];
};
Here is the data structure of QByteArray. This is a incomplete structure and it will be modify when qt 5.0 comes.
I always use append () function. So let’s set it.
QByteArray &QByteArray::append(const QByteArray &ba)
{
if ((d == &shared_null || d == &shared_empty) && !IS_RAW_DATA(ba.d)) {
*this = ba;
} else if (ba.d != &shared_null) {
if (d->ref != 1 || d->size + ba.d->size > d->alloc)
realloc(qAllocMore(d->size + ba.d->size, sizeof(Data)));
memcpy(d->data + d->size, ba.d->data, ba.d->size);
d->size += ba.d->size;
d->data[d->size] = '/0';
}
return *this;
}
Here is the first reason, if (d->ref != 1 || d->size + ba.d->size > d->alloc)
realloc(qAllocMore(d->size + ba.d->size, sizeof(Data)));
I always call the ‘append ()’ function, and it will be dispensed the memory space again. It’s a slow action. If I call the resize function, before calling append () function several times.
In this class, there are some safe expand functions of c library. But they also has some problem. Such as this one.
char *qstrcpy(char *dst, const char *src)
{
if (!src)
return 0;
#if defined(_MSC_VER) && _MSC_VER >= 1400
int len = qstrlen(src);
// This is actually not secure!!! It will be fixed
// properly in a later release!
if (len >= 0 && strcpy_s(dst, len+1, src) == 0)
return dst;
return 0;
#else
return strcpy(dst, src);
#endif
}
Here, I find some useful ASCII,
c >= 0x61 && c <= 0x7A) // ALPHA a~z
(c >= 0x41 && c <= 0x5A) // ALPHA A~Z
(c >= 0x30 && c <= 0x39) // DIGIT
c == 0x2D // -
c == 0x2E // .
c == 0x5F // _
c == 0x7E // ~
The stand memory dispense,
Data *x = static_cast<Data *>(qMalloc(sizeof(Data)));
The left, right and mid function,
QByteArray QByteArray::mid(int pos, int len) const
{
if (d == &shared_null || d == &shared_empty || pos >= d->size)
return QByteArray();
if (len < 0)
len = d->size - pos;
if (pos < 0) {
len += pos;
pos = 0;
}
if (len + pos > d->size)
len = d->size - pos;
if (pos == 0 && len == d->size)
return *this;
return QByteArray(d->data + pos, len);
}
QByteArray QByteArray::right(int len) const
{
if (len >= d->size)
return *this;
if (len < 0)
len = 0;
return QByteArray(d->data + d->size - len, len);
}
QByteArray QByteArray::left(int len) const
{
if (len >= d->size)
return *this;
if (len < 0)
len = 0;
return QByteArray(d->data, len);
}
The remove function, It is usually used.
QByteArray &QByteArray::remove(int pos, int len)
{
if (len <= 0 || pos >= d->size || pos < 0)
return *this;
detach();
if (pos + len >= d->size) {
resize(pos);
} else {
memmove(d->data + pos, d->data + pos + len, d->size - pos - len);
resize(d->size - len);
}
return *this;
}
That’s all for this class. And it’s the end of today’s analyze.
November 10, 2009 23:04