Верхний и нижний регистр
при выполнении сравнения без учета регистра более эффективно преобразовать строку в верхний или нижний регистр? Это вообще имеет значение?
Он предложил в должности что C# более эффективен с ToUpper, потому что " Microsoft оптимизировала его таким образом.- Но я тоже читал этот аргумент что преобразование ToLower против ToUpper зависит от того, что ваши строки содержат больше, и что обычно строки содержат больше символов нижнего регистра, которые делает ToLower более эффективным.
в частности, я хотел бы знать:
- есть ли способ оптимизировать ToUpper или ToLower таким образом, что один быстрее, чем другой?
- быстрее ли делать сравнение без учета регистра между строками верхнего или нижнего регистра и почему?
- существуют ли какие-либо среды программирования (например. C, C#, Python, что угодно), где один случай явно лучше, чем другой, и почему?
10 ответов:
преобразование в верхний или нижний регистр для выполнения сравнения без учета регистра неверно из-за" интересных " особенностей некоторых культур, в частности Турции. Вместо этого используйте StringComparer с соответствующими параметрами.
MSDN имеет некоторые главные направления при обработке строк. Вы также можете проверить, что ваш код проходит тест Турция.
редактировать: обратите внимание, комментарий Нила вокруг порядковый номер сравнения без учета регистра. Все это царство довольно мрачно : (
с Microsoft на MSDN:
рекомендации по использованию строк в .NET Framework
рекомендации по использованию строк
- использовать строку.ToUpperInvariant метод вместо строку.ToLowerInvariant метод при нормализации строк для сравнения.
Почему? От Microsoft:
нормализует строки в верхний регистр
существует небольшая группа символов, которые при преобразовании в нижний регистр не может сделать туда и обратно.
каков пример такого персонажа, который не может совершить поездку туда и обратно?
- Start: греческий символ Ро (U + 03f1) ϱ
- верхний: греческая столица Ро (U + 03a1) Ρ
- строчные буквы: Малый греческий Rho (U+03c1) ρ
ϱ , Ρ,ρ
вот почему, если вы хотите сделать сравнение без учета регистра, вы преобразуете строки в верхний, а не в нижний регистр.
по данным MSDN более эффективно передать строки и сказать сравнение, чтобы игнорировать case:
строку.Сравнение(strA, strB, StringComparison.OrdinalIgnoreCase) эквивалентно (но быстрее, чем) обращение
строку.Сравните (ToUpperInvariant (strA), ToUpperInvariant(strB), StringComparison.Порядковый.)
эти сравнения все равно очень быстро.
конечно, если вы сравниваете одну строку снова и снова, тогда это может не удержаться.
основываясь на строках, имеющих тенденцию иметь больше строчных записей, tolower теоретически должен быть быстрее (много сравнений, но мало назначений).
В C, или при использовании индивидуально доступных элементов каждой строки (таких как строки C или строковый тип STL в C++), это на самом деле сравнение байтов - так что сравнение
UPPERничем не отличается отlower.Если бы Вы были подлыми и загрузили свои строки в
longмассивы вместо этого, вы получите очень быстрое сравнение вся строка, потому что она может сравнивать 4 байта за раз. Однако время загрузки может сделать это не стоит.почему вам нужно знать, что быстрее? Если вы не делаете метрическую прикладную нагрузку сравнений, один запуск на пару циклов быстрее не имеет отношения к скорости общего выполнения и звучит как преждевременная оптимизация:)
Microsoft оптимизировала
ToUpperInvariant(), а неToUpper(). Разница в том, что инвариант более дружелюбен к культуре. Если вам нужно сделать сравнение без учета регистра на строках, которые могут отличаться в языке и региональных параметрах, используйте инвариант, иначе производительность инвариантного преобразования не будет иметь значения.Я не могу сказать, является ли ToUpper() или ToLower() быстрее, хотя. Я никогда не пробовал это, так как у меня никогда не было ситуации, когда производительность имела такое большое значение.
Если вы делаете сравнение строк в C# это значительно быстрее использовать .Равно () вместо преобразования обеих строк в верхний или нижний регистр. Еще один большой плюс для использования .Equals () - это то, что больше памяти не выделяется для 2 новых строк верхнего/нижнего регистра.
Это действительно не должно иметь никакого значения. С символами ASCII это определенно не имеет значения - это всего лишь несколько сравнений и немного переворачивается в любом направлении. Unicode может быть немного сложнее, так как есть некоторые символы, которые изменяют регистр странным образом, но на самом деле не должно быть никакой разницы, если ваш текст не полон этих специальных символов.
делая это правильно, должно быть небольшое, незначительное преимущество скорости, если вы конвертируете в нижний регистр, но это, как многие намекали, зависит от культуры и не наследуется в функции, но в строках, которые вы конвертируете (много букв нижнего регистра означает несколько назначений в память) - преобразование в верхний регистр быстрее, если у вас есть строка с большим количеством букв верхнего регистра.
Это Зависит. Как указано выше, простой только ASCII, его идентичный. В .NET, читать и использовать строку.Сравните это правильно для материала i18n (языки и культуры unicode). Если вы знаете что-нибудь о вероятности ввода, используйте более распространенный случай.
помните, если вы делаете несколько строк сравнивает длину является отличным первым дискриминатором.
Если вы имеете дело с чистым ASCII, это не имеет значения. Это просто OR x, 32 против an и x, 224. Юникод, я понятия не имею...
Comments