Slow MP3 tag parsing/ByteVector::replace() performance
Henry Högelow
h.hoegelow at raumfeld.com
Fri Sep 9 09:03:47 UTC 2011
Hi,
I fixed the performance issues with ByteVector::replace for the Raumfeld
devices with an algorithm allocating memory only once:
ByteVector &ByteVector::replace(const ByteVector &pattern, const
ByteVector &with)
{
if (pattern.size() == 0 || pattern.size() > size())
return *this;
const int patternSize = pattern.size();
const int withSize = with.size();
int offset = find(pattern);
// try to not allocate memory for short buffers or rare patterns
const size_t numDefaultStorageFields = 1024;
size_t defaultStorageForPatternPositions[numDefaultStorageFields];
// be prepared for any number of patterns
typedef std::list<size_t> tPatternPositions;
tPatternPositions morePatternPositions;
size_t numPatternPositions = 0;
while (offset >= 0)
{
if(numPatternPositions < numDefaultStorageFields)
{
defaultStorageForPatternPositions[numPatternPositions] = offset;
}
else
{
morePatternPositions.push_back(offset);
}
numPatternPositions++;
offset = find(pattern, offset + patternSize);
}
if(numPatternPositions)
{
// we already know the resulting buffers size, so allocate it
size_t newBuffersSize = size() + (withSize - patternSize) *
numPatternPositions;
ByteVector result(newBuffersSize);
size_t readPos = 0;
size_t writePos = 0;
tPatternPositions::const_iterator itPos = morePatternPositions.begin();
for (size_t i = 0; i < numPatternPositions; i++)
{
int patternPos = (i < numDefaultStorageFields) ?
defaultStorageForPatternPositions[i] : *(itPos++);
// copy stuff between patterns
size_t numBytesInBetween = patternPos - readPos;
::memcpy(result.data() + writePos, data() + readPos,
numBytesInBetween);
readPos += numBytesInBetween;
writePos += numBytesInBetween;
// write the new pattern
::memcpy(result.data() + writePos, with.data(), withSize);
// ignore the old pattern by advance the readPos
readPos += patternSize;
writePos += withSize;
}
// copy the rest
::memcpy(result.data() + writePos, data() + readPos, size() - readPos);
// swap the data of result with our own
std::swap(d, result.d);
}
return *this;
}
Best, Henry
--
Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/
More information about the taglib-devel
mailing list