다음과 같이 한 줄에 20자를 포함하는 텍스트 파일이 있다고 가정해 보겠습니다.
wertzuiopasdfghjkl<
asdfghjkl<yxcvbnm,.-
<yxcvbnm,.-123456789
1234567890QWERTZUIOP
QWERTZUIOPASDFGHJKL<
등...
줄에 동일한 문자가 두 개 이상 포함되기를 원합니다 grep
.
grep '\(.\).*\1' n20x1M
역참조 포함. 내 컴퓨터에서는 일치 항목이 없는 백만 개의 행을 처리하는 데 15.7초가 걸립니다.
행 수를 두 배로 늘리면 사용된 CPU 시간도 예상대로 두 배인 31.4로 늘어납니다.
또한 20개가 아닌 28개의 열이 있으면 시간이 두 배로 늘어날 것으로 예상합니다(20자는 테스트할 수 있는 190개의 조합을 제공하고 28자는 378개의 가능한 조합을 제공합니다). 하지만 내 컴퓨터에서는 28.2초밖에 되지 않습니다.
그렇다면 역참조 속도 저하가 순전히 조합 수로만 테스트되는 것은 아닌가요? 나는 이것을 시도했습니다 :
grep '^\(.\).*\1' n20x1M
이렇게 하면 조합 수가 190개에서 단 19개로 크게 줄어듭니다. 첫 번째 문자를 읽고 나머지 문자와 일치하는지 확인하세요. 1.6초 밖에 걸리지 않지만 실제로는 2.8초가 걸립니다!
행을 메모리로 읽고 캐싱하는 데 약간의 오버헤드가 있을 수 있습니까? 아니, 만약 내가 그렇게 한다면
grep '.*_' n20x1M
처리 시간은 단 0.004초! 기본적으로 동일한 작업(20자 줄에서 문자 검색)을 수행하지만 단순히 고정 문자를 제공하지 않고 나머지 19자 중 해당 줄의 첫 번째 문자를 검색하면 인수 이상의 결과를 얻습니다. 1000입니다!
내 이해에 문제가 있습니까?
역참조로 인해 숨겨진 오버헤드가 너무 많이 발생합니까?
아니면 GNU 정규식에서 역참조가 제대로 구현되지 않았습니까?
여기서 무슨 일이 일어나고 있는지 설명할 수 있는 사람이 있나요?
성능을 향상시키려면 어떻게 해야 합니까?
고쳐 쓰다 @Sundeep은 느린 역참조에 대한 면책조항을 언급했습니다. 하지만 이는 가능한 해결책이 너무 많아서 계산된 것입니다. 나는 이것을 예상했지만, 복잡성을 추가하지 않더라도 이를 사용하면 추가 페널티가 있습니다.
이는 구현 문제인 것 같습니다. 옵션을 사용한 그의 다른 팁과 마찬가지로 -P
속도 향상이 15.4초에서 2.0초로 늘어났습니다!
앵커가 있는 간단한 경우의 ^
속도는 2.8초에서 0.25초로 향상되지만 여전히 고정 문자 검색 요구 사항(0.004초)을 충족하지 못합니다. 흥미롭게도 option을 사용하면 -P
고정 문자 대소문자가 0.13초로 느려지므로 역참조 페널티는 더 작지만 전체적인 페널티에 더 가깝습니다.
불행하게도 저는 MacOS나 역참조를 주로 사용하는 버전을 사용 -P
하지 않습니다.grep
sed