egrep [wW] [oO] [rR] [dD]가 grep -i 단어보다 빠른 이유는 무엇입니까? -iq “thats” testfile real

내가 사용하고 grep -i더 자주 나는 그것보다 느린 것을 발견 egrep나는 각 문자의 대소에 대해 일치 상당 :

$ time grep -iq "thats" testfile

real    0m0.041s
user    0m0.038s
sys     0m0.003s
$ time egrep -q "[tT][hH][aA][tT][sS]" testfile

real    0m0.010s
user    0m0.003s
sys     0m0.006s

않는 grep -i그 추가 시험을 egrep하지 않는 이유는 무엇입니까?



답변

grep -i 'a'grep '[Aa]'ASCII 전용 로케일 과 동일합니다 . 유니 코드 로캘에서 문자 등가 및 변환은 복잡 할 수 있으므로 grep어떤 문자가 같은지 확인하려면 추가 작업이 필요할 수 있습니다. 관련 로케일 설정은입니다 LC_CTYPE. 이는 바이트가 문자로 해석되는 방식을 결정합니다.

내 경험상 grepUTF-8 로켈에서 호출하면 GNU 가 느려질 수 있습니다. ASCII 문자 만 검색한다는 것을 알고 있다면 ASCII 전용 로케일로 호출하는 것이 더 빠를 수 있습니다. 나는 그것을 기대한다

time LC_ALL=C grep -iq "thats" testfile
time LC_ALL=C egrep -q "[tT][hH][aA][tT][sS]" testfile

구별 할 수없는 타이밍을 만들어냅니다.

즉, grep데비안 jessie 에서 GNU로 찾은 결과를 재현 할 수는 없습니다 (그러나 테스트 파일을 지정하지 않았습니다). ASCII 로캘 ( LC_ALL=C)을 설정하면 grep -i더 빠릅니다. 효과는 문자열의 정확한 특성에 따라 달라집니다. 예를 들어 반복되는 문자가있는 문자열은 성능을 저하시킵니다 ( 예상 ).


답변

호기심으로 아치 리눅스 시스템에서 이것을 테스트했습니다.

$ uname -r
4.4.5-1-ARCH
$ df -h .
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           3.9G  720K  3.9G   1% /tmp
$ dd if=/dev/urandom bs=1M count=1K | base64 > foo
$ df -h .
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           3.9G  1.4G  2.6G  35% /tmp
$ for i in {1..100}; do /usr/bin/time -f '%e' -ao grep.log grep -iq foobar foo; done
$ for i in {1..100}; do /usr/bin/time -f '%e' -ao egrep.log egrep -q '[fF][oO][oO][bB][aA][rR]' foo; done

$ grep --version
grep (GNU grep) 2.23
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Mike Haertel and others, see <http://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.

그런 다음 일부 통계 는 단일 명령으로 숫자 목록의 최소, 최대, 중간 및 평균을 얻는 방법이 있습니까? :

$ R -q -e "x <- read.csv('grep.log', header = F); summary(x); sd(x[ , 1])"
> x <- read.csv('grep.log', header = F); summary(x); sd(x[ , 1])
       V1
 Min.   :1.330
 1st Qu.:1.347
 Median :1.360
 Mean   :1.362
 3rd Qu.:1.370
 Max.   :1.440
[1] 0.02322725
>
>
$ R -q -e "x <- read.csv('egrep.log', header = F); summary(x); sd(x[ , 1])"
> x <- read.csv('egrep.log', header = F); summary(x); sd(x[ , 1])
       V1
 Min.   :1.330
 1st Qu.:1.340
 Median :1.360
 Mean   :1.365
 3rd Qu.:1.380
 Max.   :1.430
[1] 0.02320288
>
>

나는 en_GB.utf8로케일에 있지만 시간은 거의 구별 할 수 없다.