2012-12-03 21 views
7

यह प्रश्न this other one से प्रेरित है।कैप्चरिंग से लुकहेड (कभी-कभी) तेज क्यों है?

s/,(\d)/$1/ से s/,(?=\d)// की तुलना में: पूर्व में केवल अंक को बदलने के लिए एक कैप्चर समूह का उपयोग करता है लेकिन अल्पविराम नहीं, बाद वाला यह निर्धारित करने के लिए एक लुकहेड का उपयोग करता है कि अल्पविराम एक अंक से सफल होता है या नहीं। उत्तरार्द्ध कभी-कभी तेज़ क्यों होता है, जैसा कि this answer में चर्चा की गई है?

+1

दो regexes पर कुछ बेंच मार्किंग परीक्षण कर मैं वास्तव में किसी भी बड़ा अंतर निर्धारित नहीं कर सकता। दोनों बहुत तेज़ हैं। ध्यान दें कि यह इन regexes पर लागू होता है, कैप्चरिंग बनाम देखो। – TLP

+4

यह स्पष्ट है: डेटा कॉपी करने के लिए समूह बल को कैप्चर करें और फिर प्रतिस्थापन पर '$ 1' की इंटरपोलेशन की आवश्यकता है, जबकि दूसरा रेगेक्स बस ढूंढ/चेक/निकालें। हालांकि, गति में अंतर अदृश्य होना चाहिए। – PSIAlt

उत्तर

4

दो दृष्टिकोण अलग-अलग चीजें करते हैं और विभिन्न प्रकार के ओवरहेड लागत होते हैं। जब आप कैप्चर करते हैं, तो पर्ल को कैप्चर किए गए टेक्स्ट की प्रतिलिपि बनाना पड़ता है। खपत के बिना आगे देखो; इसे उस स्थान को चिह्नित करना होगा जहां यह शुरू होता है। आप देख सकते हैं क्या re 'debug' pragma का उपयोग करके हो रहा है:

use re 'debug'; 
my $capture = qr/,(\d)/; 
 
Compiling REx ",(\d)" 
Final program: 
    1: EXACT (3) 
    3: OPEN1 (5) 
    5: DIGIT (6) 
    6: CLOSE1 (8) 
    8: END (0) 
anchored "," at 0 (checking anchored) minlen 2 
Freeing REx: ",(\d)" 
use re 'debug'; 
my $lookahead = qr/,(?=\d)/; 
 
Compiling REx ",(?=\d)" 
Final program: 
    1: EXACT (3) 
    3: IFMATCH[0] (8) 
    5: DIGIT (6) 
    6: SUCCEED (0) 
    7: TAIL (8) 
    8: END (0) 
anchored "," at 0 (checking anchored) minlen 1 
Freeing REx: ",(?=\d)" 

मैं देखने के लिए आगे ज्यादातर मामलों में कब्जा करने की तुलना में तेजी होने की उम्मीद थी, लेकिन अन्य धागा में बताया गया है regex प्रदर्शन डेटा निर्भर हो सकता है।

+0

मुझे 'री' प्रज्ञा के बारे में सोचना चाहिए था। धन्यवाद! – mpe

-1

हमेशा की तरह, जब आप कोड के दो टुकड़े का जो पता करने के लिए तेजी से काम करता है चाहते हैं, तो आप इसे परीक्षण करने के लिए है:

#!/usr/bin/perl 

use 5.012; 
use warnings; 
use Benchmark qw<cmpthese>; 

say "Extreme ,,,:"; 
my $Text = ',' x (my $LEN = 512); 
cmpthese my $TIME = -10, my $CMP = { 
    capture => \&capture, 
    lookahead => \&lookahead, 
}; 

say "\nExtreme ,0,0,0:"; 
$Text = ',0' x $LEN; 
cmpthese $TIME, $CMP; 

my $P = 0.01; 
say "\nMixed (@{[$P * 100]}% zeros):"; 
my $zeros = $LEN * $P; 
$Text = ',' x ($LEN - $zeros) . ',0' x $zeros; 
cmpthese $TIME, $CMP; 

sub capture { 
    local $_ = $Text; 
    s/,(\d)/$1/; 
} 

sub lookahead { 
    local $_ = $Text; 
    s/,(?=\d)//; 
} 

बेंचमार्क तीन अलग-अलग मामलों का परीक्षण करती है:

  1. केवल ', '
  2. केवल', 0 '
  3. 1%', 0 ', बाकी', '

मेरी मशीन पर और मेरे पर्ल संस्करण के साथ, यह इन परिणामों का उत्पादन:

Extreme ,,,: 
      Rate capture lookahead 
capture 23157/s  --  -1% 
lookahead 23362/s  1%  -- 

Extreme ,0,0,0: 
       Rate capture lookahead 
capture 419476/s  --  -65% 
lookahead 1200465/s  186%  -- 

Mixed (1% zeros): 
      Rate capture lookahead 
capture 22013/s  --  -4% 
lookahead 22919/s  4%  -- 

इन परिणामों धारणा लुक-आगे संस्करण कैप्चरिंग की तुलना में काफी तेजी से, लगभग केवल अल्पविराम के के मामले के अलावा है कि substantiates। और वास्तव में यह आश्चर्य की बात नहीं है क्योंकि पीएसआईआईएलटी ने अपनी टिप्पणी में पहले से ही समझाया है।

संबंध है, मथायस

+1

प्रश्न _which_ तेज नहीं है, लेकिन _why_। –

+0

मुझे पता है कि इसका परीक्षण कैसे करें और वास्तव में, मैंने स्वयं ऐसा किया है। प्रदर्शन के लिए धन्यवाद, यद्यपि; आपके परिणाम बहुत ही illustrative हैं! – mpe