2011-11-25 3 views
5


나는 이것을 최적화하기 위해 일부 코드에서 이것을 발견했습니다. 여기 는 snipet입니다 : 정상적인 Java 정규식 동작입니까?

tempString = bigBuffer.replaceAll("\\n", ""); 
tempString = tempString.replaceAll("\\t", ""); 

가 그럼 난 현명하게 정규식을 사용하기로 결정 난 이런 짓을 :

친구가 대신이 일을 나에게 말했다 그런
tempString = bigBuffer.replaceAll("[\\n\\t]", ""); 

:

tempString = bigBuffer.replaceAll("\\n|\\t", ""); 

필자가 변경 한 결과를 알고 싶기 때문에 필자는 그것이 좋은 최적화인지 확인하기위한 테스트를 수행했다. 따라서 (Java 버전 "1.6.0_27")의 결과는 첫 번째 코드가 참조 100 % 인 것입니다.

파이프를 사용하면 121 %이므로 작업 수행에 더 많은 시간이 걸립니다.

대괄호로 52 %이므로 작업을 수행하는 데 소요되는 시간이 적습니다.

정규 표현식이 동일해야하는 곳에서 정규 표현식이 다르게 작동하는 이유는 무엇입니까?

마틴

+0

왜 동일해야합니까? – BoltClock

+0

같은 일을하기 때문에 그것이 같아야한다고 생각합니다. 파이프가 단일 문자와 함께 사용될 때 컴파일러에 최적화가 필요할 수도 있습니다. – Martin

답변

4

첫 번째 코드는 두 번 bigBuffer을 통해 새로운 라인을 교체 처음보고, 두 번째 시간 탭을 대체합니다.

두 번째 코드 스 니펫은 bigBuffer를 통해 한 번만 검색하여 각 문자가 하나인지 다른지 확인합니다. 이렇게하면 절반 만에 속도가 완료됩니다.

3 위 코드 스 니펫은 컴파일이 잘못되어 첫 번째 코드의 알고리즘이 특히 나쁜 버전이됩니다. 물론 정규식 컴파일을 통해 경로를 신중하게 검토하지는 않습니다.

우수한 테스트 작업. 상대 타이밍 (백분율 기반)은 유용하며 절대 타이밍 (밀리 초 또는 일부)은 그렇지 않습니다.

2

일반적으로 문자 클래스 ([abc])는 동등한 변경 (a|b|c)보다 더 효율적 인 경향이 있으므로 친구가 그 이유를 알 수없는 이유를 모르겠습니다. 그러나 Java에서는 Latin1 레퍼토리의 문자 (즉 처음 256 개의 유니 코드 코드 포인트)와 만 일치하는 문자 클래스가 더욱 최적화됩니다. 이것이 아마 두 번째와 세 번째 기술간에 큰 차이가 나는 이유입니다.

다시 Java로만 제공됩니다. Perl에서, 나는 alternation과 character class의 차이를 무시할 수있을 것이라고 기대할 것이다. 그것은 훨씬 더 성숙한 구현이다. 그리고 grep에서는 세 가지 방법 중 어떤 것이 사용되던간에 차이를 측정하는 것은 어려울 것입니다.

그러나 일반적으로 문자 클래스 또는 대체 문자 중 하나를 선택하는 경우 문자 클래스를 선호해야합니다. 더 빠를 수는 없지만 속도가 느리지는 않습니다. 부적절하게 사용하면 교대로 인해 성능이 저하 될 수 있습니다.

+0

엄지 손가락의 규칙에 감사드립니다, 나는 내 친구가 그것에 대해 알고 있는지 확인합니다. – Martin

관련 문제