Способ эффективного сравнения строк в С++

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

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

или

if (a == b)

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

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

Спасибо.

Ответы

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

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

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

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

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

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

Ответ 8

Возможно, а может и не

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

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

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

Привет

БВУ