From 15d3c3c71aa534dfd087273712f9e720a23f63ab Mon Sep 17 00:00:00 2001 From: Scott Wheeler Date: Wed, 7 Apr 2004 06:00:05 +0000 Subject: [PATCH] Several optimizations that came from KCacheGrind / calltree fun. Basically they fall into the categories: - Don't convert things before you need to - When you do, use more effecient copy constructors / assignment operators (i.e. when copying prefer memcpy to a for loop and when that's not possible use an iterator instead of operator[]) git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@301896 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- mpeg/id3v2/id3v2framefactory.cpp | 2 +- mpeg/id3v2/id3v2framefactory.h | 2 +- toolkit/tbytevector.cpp | 34 ++++++++++--------- toolkit/tstring.cpp | 58 +++++++++++++++++++++++++------- 4 files changed, 66 insertions(+), 30 deletions(-) diff --git a/mpeg/id3v2/id3v2framefactory.cpp b/mpeg/id3v2/id3v2framefactory.cpp index d134715b..23ab78a3 100644 --- a/mpeg/id3v2/id3v2framefactory.cpp +++ b/mpeg/id3v2/id3v2framefactory.cpp @@ -252,7 +252,7 @@ bool FrameFactory::updateFrame(Frame::Header *header) const // private members //////////////////////////////////////////////////////////////////////////////// -void FrameFactory::convertFrame(const ByteVector &from, const ByteVector &to, +void FrameFactory::convertFrame(const char *from, const char *to, Frame::Header *header) const { if(header->frameID() != from) diff --git a/mpeg/id3v2/id3v2framefactory.h b/mpeg/id3v2/id3v2framefactory.h index 544b0f0e..43e5da6b 100644 --- a/mpeg/id3v2/id3v2framefactory.h +++ b/mpeg/id3v2/id3v2framefactory.h @@ -124,7 +124,7 @@ namespace TagLib { * \a to. If the frame matches the \a from pattern and converts the frame * ID in the \a header or simply does nothing if the frame ID does not match. */ - void convertFrame(const ByteVector &from, const ByteVector &to, + void convertFrame(const char *from, const char *to, Frame::Header *header) const; static FrameFactory *factory; diff --git a/toolkit/tbytevector.cpp b/toolkit/tbytevector.cpp index 28d31ed0..c67662cd 100644 --- a/toolkit/tbytevector.cpp +++ b/toolkit/tbytevector.cpp @@ -26,6 +26,10 @@ #include "tbytevector.h" +// This is a bit ugly to keep writing over and over again. + +#define DATA(x) (&(x->data[0])) + namespace TagLib { static const uint crcTable[256] = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, @@ -285,7 +289,7 @@ void ByteVector::setData(const char *data, uint length) detach(); resize(length); - ::memcpy(&(d->data[0]), data, length); + ::memcpy(DATA(d), data, length); } void ByteVector::setData(const char *data) @@ -301,12 +305,12 @@ char *ByteVector::data() // http://www.informit.com/isapi/product_id~{9C84DAB4-FE6E-49C5-BB0A-FB50331233EA}/content/index.asp detach(); - return &(d->data[0]); + return DATA(d); } const char *ByteVector::data() const { - return &(d->data[0]); + return DATA(d); } ByteVector ByteVector::mid(uint index, uint length) const @@ -402,7 +406,7 @@ void ByteVector::append(const ByteVector &v) uint originalSize = d->size; resize(d->size + v.d->size); - ::memcpy(&(d->data[0]) + originalSize, v.data(), v.size()); + ::memcpy(DATA(d) + originalSize, DATA(v.d), v.size()); } void ByteVector::clear() @@ -418,15 +422,15 @@ TagLib::uint ByteVector::size() const ByteVector &ByteVector::resize(uint size, char padding) { - d->size = size; - - if(d->data.size() < size) { + if(d->size < size) { d->data.reserve(size); - d->data.insert(d->data.end(), size - d->data.size(), padding); + ::memset(DATA(d), padding, size - d->size); } else d->data.erase(d->data.begin() + size, d->data.end()); + d->size = size; + return *this; } @@ -507,15 +511,10 @@ char &ByteVector::operator[](int index) bool ByteVector::operator==(const ByteVector &v) const { - if(size() != v.size()) + if(d->size != v.d->size) return false; - for(uint i = 0; i < size(); i++) { - if(at(i) != v.at(i)) - return false; - } - - return true; + return ::memcmp(data(), v.data(), size()) == 0; } bool ByteVector::operator!=(const ByteVector &v) const @@ -525,7 +524,10 @@ bool ByteVector::operator!=(const ByteVector &v) const bool ByteVector::operator==(const char *s) const { - return operator==(fromCString(s)); + if(d->size != ::strlen(s)) + return false; + + return ::memcmp(data(), s, d->size) == 0; } bool ByteVector::operator!=(const char *s) const diff --git a/toolkit/tstring.cpp b/toolkit/tstring.cpp index cb82b70b..9f1142d9 100644 --- a/toolkit/tstring.cpp +++ b/toolkit/tstring.cpp @@ -88,8 +88,14 @@ String::String(const std::string &s, Type t) return; } - for(std::string::const_iterator it = s.begin(); it != s.end(); it++) - d->data += uchar(*it); + int length = s.length(); + d->data.resize(length); + wstring::iterator targetIt = d->data.begin(); + + for(std::string::const_iterator it = s.begin(); it != s.end(); it++) { + *targetIt = uchar(*it); + ++targetIt; + } prepare(t); } @@ -115,8 +121,15 @@ String::String(const char *s, Type t) return; } - for(int i = 0; s[i] != 0; i++) - d->data += uchar(s[i]); + int length = ::strlen(s); + d->data.resize(length); + + wstring::iterator targetIt = d->data.begin(); + + for(int i = 0; i < length; i++) { + *targetIt = uchar(s[i]); + ++targetIt; + } prepare(t); } @@ -146,12 +159,25 @@ String::String(const ByteVector &v, Type t) d = new StringPrivate; if(t == Latin1 || t == UTF8) { - for(uint i = 0; i < v.size() && v[i]; i++) - d->data += uchar(v[i]); + + d->data.resize(v.size()); + wstring::iterator targetIt = d->data.begin(); + for(ByteVector::ConstIterator it = v.begin(); it != v.end() && (*it); ++it) { + *targetIt = uchar(*it); + ++targetIt; + } } else { - for(uint i = 0; i + 1 < v.size() && combine(v[i], v[i + 1]); i += 2) - d->data += combine(v[i], v[i + 1]); + d->data.resize(v.size() / 2); + wstring::iterator targetIt = d->data.begin(); + + for(ByteVector::ConstIterator it = v.begin(); + it + 1 != v.end() && combine(*it, *(it + 1)); + it += 2) + { + *targetIt = combine(*it, *(it + 1)); + ++targetIt; + } } prepare(t); } @@ -516,8 +542,14 @@ String &String::operator=(const char *s) d = new StringPrivate; - for(int i = 0; s[i] != 0; i++) - d->data += uchar(s[i]); + int length = ::strlen(s); + d->data.resize(length); + + wstring::iterator targetIt = d->data.begin(); + for(int i = 0; i < length; i++) { + *targetIt = uchar(s[i]); + ++targetIt; + } return *this; } @@ -532,9 +564,11 @@ String &String::operator=(const ByteVector &v) wstring::iterator targetIt = d->data.begin(); uint i = 0; - for(; i < v.size() && v[i]; i++) { - *targetIt = uchar(v[i]); + + for(ByteVector::ConstIterator it = v.begin(); it != v.end() && (*it); ++it) { + *targetIt = uchar(*it); ++targetIt; + ++i; } // If we hit a null in the ByteVector, shrink the string again.