эффективный способ сравнения строк в C ++ - PullRequest
14 голосов
/ 10 ноября 2010

Эффективно ли сравнивать строку с другой строкой или строковым литералом вроде этого?

string a;
string b;
if (a == "test")

или

if (a == b)

Мой коллега попросил меня использовать memcmp

Любые комментарии по этому поводу?

Спасибо.

Ответы [ 8 ]

42 голосов
/ 10 ноября 2010

Да, используйте a == b, не слушайте своего коллегу.

Вы всегда должны отдавать предпочтение удобочитаемости кода и использовать STL, а не использовать функции C, если у вас нет определенного узкого места в вашей программе, которое необходимо оптимизировать, и вы доказали, что это действительно узкое место.

17 голосов
/ 10 ноября 2010

Очевидно, что вы должны использовать a == b и полагаться на его реализацию.

Для записи, std::char_traits<char>::compare() в популярной реализации опирается на memcmp(), поэтому вызов его напрямую будет только более болезненным и подверженным ошибкам.

9 голосов
/ 10 ноября 2010

Если вам действительно нужно знать, вы должны написать тестовое приложение и посмотреть, каково время.

При этом вы должны полагаться на то, что предоставленная реализация будет достаточно эффективной. Обычно это так.

8 голосов
/ 10 ноября 2010

Я думаю, что ваш коллега немного обеспокоен возможной оптимизацией.

  • memcmp не предназначен для сравнения строк (это будет strcmp)
  • , чтобы сравнивать только размер самой короткой строки, вам потребуется strlen для обеих строк
  • memcmp возвращает <0, = 0,> 0, что неприятно всегда помнить
  • strcmp и strlen могут вызвать странное поведение с плохими строками в стиле c (не заканчивающимися на \ 0 или null)
7 голосов
/ 11 ноября 2010

Это менее эффективно. std::string::operator== может сделать одну очень быструю проверку на одинаковую длину. Если длина строки не одинакова (довольно часто), он может вернуть false, не глядя даже на один символ.

В C memcmp нужно указать длину для сравнения, что означает, что вам нужно вызвать strlen дважды, и это смотрит на все символы в обеих строках.

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

STL рекомендуется всегда отдавать предпочтение функциям-членам для выполнения определенной задачи. В данном случае это basic_string::operator==.

Ваш коллега должен немного подумать о C ++ и уйти от CRT. Иногда я думаю, что это просто из-за страха перед неизвестным - если вы можете обучить работе с C ++, возможно, вам будет легче.

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

Только если скорость очень важна

Использовать строки фиксированного размера (32-64 байта очень хорошо), инициализируются всеми нулями и затем заполняются строковыми данными. (Обратите внимание, что здесь под «строкой» я подразумеваю необработанный код C или собственный пользовательский класс строк, , а не класс std :: string.)

Используйте memcpy и memcmp для сравнения этих строк, всегда используя фиксированный размер буфера.

Вы можете получить даже быстрее, чем memcmp, если убедитесь, что ваши строковые буферы выровнены по 16 байтов, поэтому вы можете использовать SSE2, и вам нужно только проверить на равенство, а не больше или меньше, чем. Даже без SSE2 вы можете сравнивать равенство, используя вычитание в кусках размером в слово.

Причина, по которой эти методы ускоряют процесс, заключается в том, что они убирают тест сравнения байтов за байтами из уравнения. Поиск завершающего '\0' или байта, который отличается, стоит дорого, потому что тестирование и ветвление трудно предсказать и передать.

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

Может быть, а может и нет

Если ваша реализация C ++ использует высокооптимизированный memcmp (как в GCC) и сравнение строк C ++ делает тривиальный эквивалент while(*p++ == *q++) ..., тогда да,memcmp будет быстрее для больших строк , потому что он использует сравнение нескольких символов за раз и выровненные 32-битные нагрузки .

На более коротких строках эти оптимизации не будут видны во времени - но на более крупных строках (около 10 КБ или около того) ускорение должно быть четко видно.

Ответ: это зависит ;-) Проверьте реализацию строк C ++.

С уважением

rbo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...