strncpy занимает много времени
Недавно я столкнулся с некоторым устаревшим кодом и заметил, что иногда (не всегда) следующий фрагмент кода выполняется очень долго.
#define NUM_OF_RECORDS 100000
char* pzBuffer = new char[NUM_OF_RECORDS + 1];
strncpy(pzBuffer, "", NUM_OF_RECORDS);
Кажется, цель состоит в том, чтобы инициализировать pzBuffer, и я согласен, что memcpy или memset будет лучшим выбором. Я пытаюсь выяснить, почему это занимает время, и если использование здесь правильно.
2 ответа
С помощью memset()
мог сделать лучше по следующей причине:
1)strncpy()
работает на отдельном уровне 'char', что означает, что он будет перебирать все символы один за другим (~NUM_OF_RECORDS
итерации в вашем случае).
2)memset()
работает на уровне блока, где блок состоит, скажем, из N байтов. Хотя это означает прохождение отдельных байтов блока, эта функция предназначена для оптимизации блоков большого размера, что часто приводит к повышению производительности при использовании блоков большого размера.
Я бы порекомендовал создавать варианты вашего кода 1) с помощью memset 2) другие с помощью strncpy. Затем скомпилируйте их оба, чтобы сгенерировать ассемблерный код, и выясните разницу между инструкциями.
http://unix.superglobalmegacorp.com/BSD4.4Lite/newsrc/libkern/strncpy.c.html
Например, стандартная реализация strncpy заполняет все остальные элементы массива нулями, несмотря ни на что. Так что на это нужно время.
do {
if ((*d++ = *s++) == 0) {
/* NUL pad the remaining n-1 bytes */
while (--n != 0)
*d++ = 0;
break;
}
} while (--n != 0);