대문자 대 소문자 많은 소문자가 포함되어 ToLower를 더 효율적으로

대소 문자를 구분하지 않는 비교를 할 때 문자열을 대문자 또는 소문자로 변환하는 것이 더 효율적입니까? 그것이 중요합니까?

이 SO 게시물 에서는 “Microsoft가 그렇게 최적화했기 때문에 C #이 ToUpper와 함께 더 효율적 이라고 제안 합니다.” 그러나 ToLower 대 ToUpper를 변환하는 것은 문자열에 더 많은 내용이 포함되어 있고 일반적으로 문자열에 더 많은 소문자가 포함되어 ToLower를 더 효율적으로 만든다는 이 주장 을 읽었습니다 .

특히 다음 사항을 알고 싶습니다.

  • 하나가 다른 것보다 빠르도록 ToUpper 또는 ToLower를 최적화하는 방법이 있습니까?
  • 대문자 또는 소문자 문자열을 대소 문자를 구분하지 않고 비교하는 것이 더 빠르며 그 이유는 무엇입니까?
  • 한 경우가 다른 경우보다 분명히 나은 프로그래밍 환경 (예 : C, C #, Python 등)이 있습니까? 그 이유는 무엇입니까?



답변

대소 문자를 구분하지 않고 비교하기 위해 대문자 또는 소문자로 변환하는 것은 일부 문화권, 특히 터키의 “흥미로운”기능으로 인해 올바르지 않습니다. 대신 적절한 옵션과 함께 StringComparer를 사용하십시오.

MSDN에는 문자열 처리에 대한 몇 가지 훌륭한 지침이 있습니다. 또한 코드가 Turkey 테스트를 통과하는지 확인할 수도 있습니다 .

편집 : 서수 대소 문자를 구분하지 않는 비교에 대한 Neil의 설명을 참고하십시오 . 이 전체 영역은 꽤 어둡습니다 🙁


답변

에서 마이크로 소프트 MSDN에 :

.NET Framework에서 문자열을 사용하기위한 모범 사례

문자열 사용에 대한 권장 사항

왜? 에서 마이크로 소프트 :

문자열을 대문자로 정규화

소문자로 변환 할 때 왕복 할 수없는 작은 문자 그룹이 있습니다.

왕복 할 수없는 캐릭터의 예는 무엇입니까?

  • 시작 : 그리스로 기호 (U + 03f1) ϱ
  • 대문자 : Capital Greek Rho (U + 03a1) Ρ
  • 소문자 : 작은 그리스어 Rho (U + 03c1) ρ

ϱ, Ρ , ρ

.NET 바이올린

Original: ϱ
ToUpper: Ρ
ToLower: ρ

그렇기 때문에 대소 문자를 구분하지 않는 비교를하려면 문자열을 소문자가 아닌 대문자로 변환해야합니다.

따라서 하나를 선택해야하는 경우 대문자를 선택하십시오 .


답변

MSDN 에 따르면 문자열을 전달하고 대소 문자를 무시하도록 비교하는 것이 더 효율적입니다.

String.Compare (strA, strB, StringComparison.OrdinalIgnoreCase)는 호출 과 동일 하지만 (보다 빠릅니다 )

String.Compare (ToUpperInvariant (strA), ToUpperInvariant (strB), StringComparison.Ordinal).

이러한 비교는 여전히 매우 빠릅니다.

물론, 하나의 문자열을 계속해서 비교한다면 이것은 유지되지 않을 수 있습니다.


답변

더 많은 소문자 항목을 갖는 경향이있는 문자열을 기반으로, ToLower는 이론적으로 더 빠릅니다 (많은 비교이지만 할당은 거의 없음).

C에서 또는 각 문자열의 개별적으로 액세스 할 수있는 요소 (예 : C 문자열 또는 C ++의 STL 문자열 유형)를 사용하는 경우 실제로는 바이트 비교이므로 비교 UPPERlower.

교활하고 문자열을 long대신 배열에 로드 하면 한 번에 4 바이트를 비교할 수 있기 때문에 전체 문자열에 대해 매우 빠른 비교를 얻을 수 있습니다. 그러나로드 시간으로 인해 가치가 없을 수 있습니다.

어떤 것이 더 빠른지 알아야하는 이유는 무엇입니까? 비교의 통계적 버트로드를 수행하지 않는 한, 몇 사이클 더 빠르게 실행하는 것은 전체 실행 속도와 관련이 없으며 조기 최적화처럼 들립니다. 🙂


답변

마이크로 소프트는 최적화있다 ToUpperInvariant(), 없다 ToUpper(). 차이점은 불변성이 더 문화 친화적이라는 것입니다. 문화권이 다를 수있는 문자열에 대해 대 / 소문자를 구분하지 않는 비교를 수행해야하는 경우 Invariant를 사용하십시오. 그렇지 않으면 고정 변환의 성능이 중요하지 않습니다.

ToUpper () 또는 ToLower ()가 더 빠르다고 말할 수 없습니다. 성능이 그다지 중요한 상황이 없었기 때문에 한 번도 시도한 적이 없습니다.


답변

C #에서 문자열 비교를 수행하는 경우 두 문자열을 모두 대문자 또는 소문자로 변환하는 대신 .Equals ()를 사용하는 것이 훨씬 빠릅니다. .Equals () 사용에 대한 또 다른 큰 장점은 2 개의 새로운 대문자 / 소문자 문자열에 더 많은 메모리가 할당되지 않는다는 것입니다.


답변

정말 중요하지 않습니다. ASCII 문자를 사용하면 확실히 문제가되지 않습니다. 단지 몇 번의 비교와 어느 방향 으로든 약간 뒤집기 만하면됩니다. 유니 코드는 이상한 방식으로 대소 문자를 바꾸는 문자가 있기 때문에 조금 더 복잡 할 수 있지만 텍스트가 특수 문자로 가득 차 있지 않으면 실제로 차이가 없어야합니다.