Вы бы предложили этот метод для копирования строк? - PullRequest
0 голосов
/ 15 ноября 2010

Чтобы достичь более высокой производительности, предложите ли вы использовать метод, описанный ниже, при копировании строк, особенно если в строке много символов, больше 12?

 unsigned char one[12]={1,2,3,4,5,6,7,8,9,10,11,12};
 unsigned char two[12];
 unsigned int (& three)[3]=reinterpret_cast<unsigned int (&)[3]>(one);
 unsigned int (& four)[3]=reinterpret_cast<unsigned int (&)[3]>(two);
 for (unsigned int i=0;i<3;i++)
  four[i]=three[i];

Ответы [ 7 ]

5 голосов
/ 15 ноября 2010

Нет, (почти) никогда. Используйте std::strcpy (хотя не в этом случае, поскольку ваши «строки» не заканчиваются нулем), или std::copy, или конструктор копирования std::string.

Эти методы оптимизированы , чтобы выполнить работу за вас. Если ваш код (или что-то подобное) оказывается быстрее, чем наивный символ за копированием символа, будьте уверены, что strcpy будет использовать его снизу. Фактически, - это , что происходит (в зависимости от архитектуры).

Не пытайтесь перехитрить современные компиляторы и фреймворки, если вы не являетесь экспертом в предметной области (и обычно даже тогда).

3 голосов
/ 15 ноября 2010

Возможно memcpy / std::copy? Разве они не были бы оптимизированы в любом случае?

2 голосов
/ 15 ноября 2010

Я полагаю, что большинство современных компиляторов уже оптимизируют копирование строк. В любом случае вам следует сравнить это, а также сравнить с memcpy, но я не думаю, что оптимизация стоит потери читабельности.

1 голос
/ 15 ноября 2010

Я согласен с другими ответами здесь.Обычно попытки оптимизировать копирование блоков чаще всего оказываются медленнее, чем обеспечивает ваша целевая ОС.Например, memcpy (), memmove () и т. П., Как правило, реализуют некоторые варианты этого алгоритма: копирование слов / полуслов / байтов с использованием регистров GP, пока вы не достигнете 16-байтового выравнивания, затем используйте SSE для копирования 4 слов за раз (16 символов за раз, при условии sizeof (char) == 1).

Опять же, вы также можете проверить производительность вашей реализации против memcpy () / strcpy () и посмотреть, что вы получите.

0 голосов
/ 15 ноября 2010

Использование str *, возможно, является самым простым способом построения строк с нулевым символом в конце по крайней мере на C.Угол производительности заключается в том, что перед тем, как на самом деле становится возможным копирование, необходимо рассчитать позицию назначения в строке назначения (то есть позицию найденного нулевого байта).Затем длина исходной строки должна быть рассчитана, чтобы у вас было достаточно памяти в месте назначения.Это увеличивает накладные расходы (чем длиннее строка) по сравнению с использованием memcpy, когда вам нужно иметь достаточно большой буфер и отслеживать, сколько байт вы использовали.

(Тогда у вас могут быть дополнительныесложность, если в настройках компилятора указаны 2-байтовые символы)

Так что, если длина строки составляет 3000 байтов, и вы добавляете строки «a», а затем «b», каждый из них потребует сканирования через 3000 и 3001 байт, прежде чем сможетзапишите два байта каждый в «a» и «b» («a» + null и «b» + null).Попробуйте оптимизировать это!Добавление «b» к «a» перед добавлением к 3000-байтовой строке будет намного быстрее.

Лично я бы использовал memcpy для строк назначения размером более 50 байтов или около того.Код становится немного сложнее, но как только вы это сделаете несколько раз, это легко.

0 голосов
/ 15 ноября 2010

Если у вас есть проблема с копированием строки, всегда есть способ llvm :: StringRef : предоставить ссылку на базовую строку, которая не может ее изменить.Атрибуты класса ограничены char const* и size_t.

. Конечно, недостатком является то, что ВЫ должны убедиться, что базовый буфер остается выделенным на время использования StringRef

0 голосов
/ 15 ноября 2010

Я не уверен, почему вы вообще используете здесь ссылки.

Сделайте это:

memcpy(two, one, sizeof(two));

Обратите внимание, что вы используете больше "байтовый массив", особенно это unsigned. Кроме того, если вы чувствуете необходимость «группировать» байты таким образом, вам больше повезет, группируя их по 4 или 8, если они соответствуют типичным размерам регистра.

...