Egrep क्यों है [wW] [oO] [rR] [dD] grep -i शब्द की तुलना में तेज़?


49

मैं 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नहीं करता है?


12
प्रयास करें grepचारों ओर के अन्य तरीके से, आप flie की डिस्क कैशिंग के बीच अंतर को मापने नहीं कर रहे हैं सुनिश्चित करने के लिए।
एइटबिटोनी

3
मेरे पास फ़ाइल को परीक्षण से पहले grep'd है, इसलिए इसे कैश किया गया है। लगभग एक ही समय यदि रिवर्स ऑर्डर में किया जाता है।
tildearrow

21
यह स्थान पर निर्भर कर सकता है: कुछ स्थान मामले की असंवेदनशीलता के लिए जटिल गणना शामिल करते हैं। GNU grep विशेष रूप से यूनिकोड से संबंधित कई स्थितियों में धीमा है। आपने किस लोकेल सेटिंग का उपयोग किया? किस यूनिक्स संस्करण के तहत? आपकी परीक्षण फ़ाइल की सामग्री क्या है?
गिल्स एसओ- बुराई को रोकें '

6
@ गिल्स अच्छा लग रहा है, यहां प्रत्येक परीक्षा 100 बार दोहराई जाती है (पूरी बात), जब तक मैं सेट नहीं करता हूं egrep, grepतब तक तेज होता है LANG=Cऔर फिर वे दोनों लगभग एक समान होते हैं।
एइटबिटोनी

2
@EightBitTony userसमय पर देखें (जिसमें डिस्क की प्रतीक्षा में समय शामिल नहीं है)। अंतर में परिमाण का क्रम है।
कास्परड

जवाबों:


70

grep -i 'a'grep '[Aa]'एक ASCII- केवल लोकेल के बराबर है । एक यूनिकोड स्थान में, वर्ण समतुल्य और रूपांतरण जटिल grepहो सकते हैं , इसलिए यह निर्धारित करने के लिए अतिरिक्त कार्य करना पड़ सकता है कि कौन से वर्ण समतुल्य हैं। प्रासंगिक लोकेल सेटिंग है LC_CTYPE, जो यह निर्धारित करती है कि बाइट्स को पात्रों के रूप में कैसे व्याख्या किया जाता है।

मेरे अनुभव में, grepUTU-8 लोकेल में आमंत्रित किए जाने पर GNU धीमा हो सकता है। यदि आप जानते हैं कि आप केवल ASCII वर्णों की खोज कर रहे हैं, तो इसे ASCII-only लोकेल में लागू करना और तेज़ हो सकता है। मुझे उम्मीद करता हूँ की

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

अप्रत्यक्ष समय का उत्पादन होगा।

कहा जा रहा है, मैं grepडेबियन जेसी पर GNU के साथ आपकी खोज को पुन: पेश नहीं कर सकता (लेकिन आपने अपनी परीक्षण फ़ाइल निर्दिष्ट नहीं की)। अगर मैं ASCII लोकेल ( LC_ALL=C) सेट करता हूं , grep -iतो तेज है। प्रभाव स्ट्रिंग की सटीक प्रकृति पर निर्भर करते हैं, उदाहरण के लिए बार-बार पात्रों के साथ एक स्ट्रिंग प्रदर्शन को कम करता है ( जिसे उम्मीद की जानी है )।


लेखक Ubuntu 14.04 का उपयोग करता है जो grep 2.10 के साथ जहाज करता है। -iमल्टीबाइट स्थानों के साथ केस-असंवेदनशील मैचों ( ) की गति में 2.17 में सुधार होना चाहिए ।
लेकेनस्टाइन

@Lekensteyn जानकर अच्छा लगा, धन्यवाद। Ubuntu 14.04 वास्तव में grep 2.16 के साथ आता है, लेकिन यह पूर्व 2.17 भी है; मैंने grep 2.20 के साथ परीक्षण किया, जो बताता है कि मैंने उसी मंदी को क्यों नहीं देखा।
गिलेस एसओ- बुराई को रोकना '

सही है, मैं गलत LTS रिलीज़ देख रहा था, Ubuntu 12.04 शिप grep 2.10 के साथ जबकि Ubuntu 14.04 grep 2.16 शामिल है।
लेकेनस्टाइन

1
मैं काफी निश्चित हूं जो किसी भी लोकेल के grep -i 'a'बराबर है grep '[Aa]'। उचित उदाहरण grep -i 'i'जो grep '[Ii]'या तो है grep '[İi]'( या ऊपर वाला डॉट के साथ अपरकेस, U + 130, तुर्की लोकेल)। हालाँकि, grepइस समानता वर्ग को लोकेल दिए जाने का कोई कारगर तरीका नहीं है ।
MSalters

15

जिज्ञासा से बाहर, मैंने एक आर्क लिनक्स सिस्टम पर इसका परीक्षण किया:

$ 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लोकल पर हूं , लेकिन समय लगभग अविभाज्य है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.