为什么egrep [wW][oO][rR][dD]比grep -i word更快?

为什么egrep [wW][oO][rR][dD]比grep -i word更快?

我使用得更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

答案1

grep -i 'a'相当于grep '[Aa]'在纯 ASCII 语言环境中。在 Unicode 语言环境中,字符等效和转换可能很复杂,因此grep可能需要做额外的工作来确定哪些字符等效。相关的区域设置是LC_CTYPE,它确定如何将字节解释为字符。

根据我的经验,grep在 UTF-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在 Debian jessie 上使用 GNU 重现您的发现(但您没有指定您的测试文件)。如果我设置 ASCII 语言环境 ( LC_ALL=C),grep -i速度会更快。影响取决于字符串的确切性质,例如,具有重复字符的字符串会降低性能(这是可以预料的)。

答案2

出于好奇,我在 Arch Linux 系统上对此进行了测试:

$ 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,但时间几乎无法区分。

相关内容