Способ эффективного сравнения строк в С++
Насколько эффективно сравнивать строку с другой строкой или строковым литералом?
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 тыс. или около того) ускорение должно быть четко видимым.
Ответ: это зависит;-) Проверьте реализацию строк на С++.
Привет
БВУ