2017-11-11 172 views
5

使用基本R字符串函数(如gsubgrep)时,是否存在任何缺点,作为习惯问题,始终指定perl = TRUE ?这有什么缺点吗?如文档所述,表达式可以做更多事情(例如,您可以使用向前看或背后的断言,或者可以使用\\U进行大小写转换),并且性能也更快,正如文档所述。基本R中的正则表达式:'perl = TRUE'与默认值(PCRE vs. TRE)

那么,有什么缺点吗?仅为了向后兼容,perl = TRUE不是默认设置吗?当perl = TRUE时,我应该知道是否存在可移植性问题?

+0

*是否有任何缺点?*否。如果您喜欢,请使用它。 –

+1

这些函数使用正则表达式。我不是专家,但我知道这些正则表达式有一些不同的“风味”AKA引擎。争论唯一的事情就是激活perl-flavor。没有缺点,据我所知 –

+0

'perl = TRUE'使模式由PCRE(而不是Perl)正则表达式引擎处理。请注意,这意味着某些模式与使用默认TRE正则表达式引擎进行分析时的工作方式不同。 –

回答

2

初步考虑

它不是比较苹果和橘子,因为PCRE正则表达式可以做的比不支持lookarounds TRE正则表达式的更多,回溯控制动词,情况改变运营商在替换模式是个好主意(实际上,它是R中使用的PCRE库的扩展)。此外,当您在TRE正则表达式的使用模式.,记住它匹配换行符,也和在PCRE模式,使.匹配换行符,你需要使用(?s)直列DOTALL修饰符.之前应该匹配任何字符,包括换行符(或类似修饰符组的(?s:.*))。

如果我们要比较的R TRE和PCRE正则表达式引擎的性能,我们应该用字面匹配与这些2个发动机相同的文本是简单的模式。在Windows 7中,Linux操作系统Ubuntu 16.04,MacOS的塞拉利昂10.12.6

基准测试我在Windows中使用[R居多,但我在Linux VM安装[R 3.2.3专门为这个测试。 MacOS的结果是从t.kalinowski's answer中借用的。

让我们比较TRE(默认)和PCRE使用微基准库(perl=TRUE)正则表达式的表现(详见benchmarking options in R):

library(microbenchmark) 

文本是一个Wikipedia article about butterflies

txt <- "Butterflies are insects in the macrolepidopteran clade Rhopalocera from the order Lepidoptera, which also includes moths. Adult butterflies have large, often brightly coloured wings, and conspicuous, fluttering flight. The group comprises the large superfamily Papilionoidea, which contains at least one former group, the skippers (formerly the superfamily \"Hesperioidea\") and the most recent analyses suggest it also contains the moth-butterflies (formerly the superfamily \"Hedyloidea\"). Butterfly fossils date to the Paleocene, which was about 56 million years ago." 

让我们试着和sub,一个很普通的sub操作R中提取括号内的最后文本:

# sub('.*\\((.*)\\).*', '\\1', txt) 
# => [1] "formerly the superfamily \"Hedyloidea\"" 
PCRE_1 <- function(text) { return(sub('.*\\((.*)\\).*', '\\1', txt, perl=TRUE)) } 
TRE_1 <- function(text) { return(sub('.*\\((.*)\\).*', '\\1', txt)) } 
test <- microbenchmark(PCRE_1(txt), TRE_1(txt), times = 500000) 
test 

结果如下:

WINDOWS 
------- 
Unit: microseconds 
     expr  min  lq  mean median  uq  max neval 
PCRE_1(txt) 163.607 165.418 168.65393 166.625 167.229 7314.588 5e+05 
    TRE_1(txt) 70.031 72.446 74.53842 73.050 74.257 38026.680 5e+05 

MacOS 
----- 
Unit: microseconds 
     expr min  lq  mean median  uq  max neval 
    PCRE_1(txt) 31.693 32.857 37.00757 33.413 35.805 43810.177 5e+05 
    TRE_1(txt) 46.037 47.199 53.06407 47.807 51.981 7702.869 5e+05 

Linux 
------ 
Unit: microseconds 
     expr min  lq  mean median  uq  max neval 
PCRE_1(txt) 10.557 11.555 13.78216 12.097 12.662 4301.178 5e+05 
    TRE_1(txt) 25.875 27.350 31.51925 27.805 28.737 17974.716 5e+05 

TRE正则表达式sub仅在Windows胜,超过2倍的速度。在MacOS和Linux上,PCRE(perl=TRUE)版本都以相似的比例获胜。

现在,让我们比较正则表达式的性能不使用回溯,在很大程度上并提取双引号内的话:

# regmatches(txt, gregexpr("\"[A-Za-z]+\"", txt)) 
# => [1] "\"Hesperioidea\"" "\"Hedyloidea\"" 
PCRE_2 <- function(text) { return(regmatches(txt, gregexpr("\"[A-Za-z]+\"", txt, perl=TRUE))) } 
TRE_2 <- function(text) { return(regmatches(txt, gregexpr("\"[A-Za-z]+\"", txt))) } 
test <- microbenchmark(PCRE_2(txt), TRE_2(txt), times = 500000) 
test 

WINDOWS 
------- 
Unit: microseconds 
     expr  min  lq  mean median  uq  max neval 
PCRE_2(txt) 324.799 330.232 349.0281 332.646 336.269 124404.14 5e+05 
    TRE_2(txt) 187.755 191.981 204.7663 193.792 196.208 74554.94 5e+05 

MacOS 
----- 
Unit: microseconds 
     expr min  lq  mean median  uq  max neval 
    PCRE_2(txt) 63.801 68.115 75.51773 69.164 71.219 47686.40 5e+05 
    TRE_2(txt) 63.825 67.849 75.20246 68.883 70.933 49691.92 5e+05 

LINUX 
----- 
Unit: microseconds 
     expr min  lq  mean median  uq  max neval 
PCRE_2(txt) 30.199 34.750 44.05169 36.151 43.403 38428.2 5e+05 
    TRE_2(txt) 37.752 41.854 52.58230 43.409 51.781 38915.7 5e+05 

最好的平均值属于Linux中的PCRE正则表达式,在MacOS上,差别几乎是疏忽,在Windows中,TRE的工作速度更快。

摘要

显然,TRE(默认)的正则表达式库工作在Windows快得多。在Linux中,PCRE正则表达式要快得多。在MacOS中,PCRE正则表达式仍然是可取的,因为在回溯模式下,PCRE正则表达式比该操作系统中的TRE快。

+0

感谢您的好评和基准。你知道为什么在['?grep'](https://stat.ethz.ch/R-manual/R-devel/library/base/html/grep.html)中说“通常PCRE会比默认正则表达式引擎“ –

+1

在我的系统(macOS 10.12)上,我得到了相反的结果(因为我无法在此评论框中使用格式化工作发布答案) –

+0

我同意tk事实上,对于几乎所有的情况,perl都比固定的更快。我认为一般来说,perl速度更快,但在某些平台和实现中可能不会。 – Hugh

0

运行@ wiktor-stribiżew的基准测试,我得到了与他不同的结果。在第一次测试中,PCRE引擎比TRE快(即,perl=TRUE更快)。在第二个基准测试中,PCRE或TRE的性能没有显着差异。

这些都是R上的版本3.4.2(2017年9月28日)运行,MACOS塞拉利昂10.12.6,i7-2675QM CPU @ 2.20GHz

``` 
txt <- "Butterflies are insects in the macrolepidopteran clade Rhopalocera from the order Lepidoptera, which also includes moths. Adult butterflies have large, often brightly coloured wings, and conspicuous, fluttering flight. The group comprises the large superfamily Papilionoidea, which contains at least one former group, the skippers (formerly the superfamily \"Hesperioidea\") and the most recent analyses suggest it also contains the moth-butterflies (formerly the superfamily \"Hedyloidea\"). Butterfly fossils date to the Paleocene, which was about 56 million years ago." 

library(microbenchmark) 

PCRE_1 <- function(text) sub('.*\\((.*)\\).*', '\\1', txt, perl=TRUE) 
TRE_1 <- function(text) sub('.*\\((.*)\\).*', '\\1', txt) 
(test <- microbenchmark(PCRE_1(txt), TRE_1(txt), times = 500000)) 
#> Unit: microseconds 
#>   expr min  lq  mean median  uq  max neval 
#> PCRE_1(txt) 31.693 32.857 37.00757 33.413 35.805 43810.177 5e+05 
#> TRE_1(txt) 46.037 47.199 53.06407 47.807 51.981 7702.869 5e+05 

PCRE_2 <- function(text) regmatches(txt, gregexpr("\"[A-Za-z]+\"", txt, perl=TRUE)) 
TRE_2 <- function(text) regmatches(txt, gregexpr("\"[A-Za-z]+\"", txt)) 
(test <- microbenchmark(PCRE_2(txt), TRE_2(txt), times = 500000)) 
#> Unit: microseconds 
#>   expr min  lq  mean median  uq  max neval 
#> PCRE_2(txt) 63.801 68.115 75.51773 69.164 71.219 47686.40 5e+05 
#> TRE_2(txt) 63.825 67.849 75.20246 68.883 70.933 49691.92 5e+05 
``` 
0

我的结果的Ubuntu 16.04, - Perl是更快, 见下文。

Unit: microseconds 
     expr min  lq mean median uq max neval cld 
PCRE_1(txt) 8.949 9.809 11.16 10.18 10.62 135299 5e+05 a 
    TRE_1(txt) 23.816 24.805 26.84 25.23 26.17 5433 5e+05 b 

Unit: microseconds 
     expr min lq mean median uq max neval cld 
PCRE_2(txt) 26.97 30.96 37.32 32.19 35.06 243164 5e+05 a 
    TRE_2(txt) 33.75 38.07 44.50 39.40 43.33 35632 5e+05 b 


Session info ----------------------------------------------------------------- 
setting value      
version R version 3.4.2 (2017-09-28) 
system x86_64, linux-gnu   
ui  RStudio (1.1.383)   
language en       
collate en_US.UTF-8     
tz  Europe/Berlin    
date  2017-11-12  



    Linux 4.4.0-93-generiC#116-Ubuntu SMP Fri Aug 11 21:17:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 

model name : Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz 
stepping : 3 
microcode : 0x9 
cpu MHz  : 3647.929 
cache size : 8192 KB