str_replace str_detect sheet regular cheat regex r string gsub stringi

regex - str_detect - str_replace r



velocidad de gsub vs longitud del patrĂ³n (1)

gsub he estado usando gsub ampliamente, y noté que los patrones cortos se ejecutan más rápido que los largos, lo que no es sorprendente. Aquí hay un código totalmente reproducible:

library(microbenchmark) set.seed(12345) n = 0 rpt = seq(20, 1461, 20) msecFF = numeric(length(rpt)) msecFT = numeric(length(rpt)) inp = rep("aaaaaaaaaa",15000) for (i in rpt) { n = n + 1 print(n) patt = paste(rep("a", rpt[n]), collapse = "") #time = microbenchmark(func(count[1:10000,12], patt, "b"), times = 10) timeFF = microbenchmark(gsub(patt, "b", inp, fixed=F), times = 10) msecFF[n] = mean(timeFF$time)/1000000. timeFT = microbenchmark(gsub(patt, "b", inp, fixed=T), times = 10) msecFT[n] = mean(timeFT$time)/1000000. } library(ggplot2) library(grid) library(gridExtra) axis(1,at=seq(0,1000,200),labels=T) p1 = qplot(rpt, msecFT, xlab="pattern length, characters", ylab="time, msec",main="fixed = TRUE" ) p2 = qplot(rpt, msecFF, xlab="pattern length, characters", ylab="time, msec",main="fixed = FALSE") grid.arrange(p1, p2, nrow = 2)

Como ves, estoy buscando un patrón que contenga a rpt[n] veces replicado. La pendiente es positiva, como se esperaba. Sin embargo, noté un pliegue en 300 caracteres con fixed=T y 600 caracteres con fixed=F y luego la pendiente parece ser aproximadamente como antes (vea la gráfica a continuación). Supongo que se debe a la memoria, el tamaño del objeto, etc. También noté que el pattern más largo permitido es de 1463 símbolos, con un tamaño de objeto de 1552 bytes.

¿Alguien puede explicar mejor el problema y por qué con 300 y 600 caracteres?

Agregado: vale la pena mencionar que la mayoría de mis patrones son de 5 a 10 caracteres, lo que me da en mis datos reales (no en la maqueta de inp en el ejemplo anterior) la siguiente sincronización.

gsub, fixed = TRUE: ~50 msec per one pattern gsub, fixed = FALSE: ~190 msec per one pattern stringi, fixed = FALSE: ~55 msec per one pattern gsub, fixed = FALSE, perl = TRUE: ~95 msec per one pattern

(Tengo 4k patrones, por lo que el tiempo total de mi módulo es de aproximadamente 200 segundos, que es exactamente de 0,05 x 4000 con gsub y corregido = VERDADERO. Es el método más rápido para mis datos y patrones)


Los pliegues pueden estar relacionados con los bits necesarios para mantener patrones de esa longitud.

Hay otra solución que se escala mucho mejor, use el operador de repetición {} para especificar cuántas repeticiones desea encontrar. Para encontrar más de 255 (8 bits máximo entero) deberá especificar perl = TRUE .

patt2 <- paste0(''a{'',rpt[n],''}'') timeRF <- microbenchmark(gsub(patt2, "b", inp, perl = T), times = 10)

Obtengo velocidades de alrededor de 2.1 ms por búsqueda sin penalización por la longitud del patrón. Eso es aproximadamente 8 veces más rápido que fijo = FALSO para longitudes de patrón pequeñas y aproximadamente 60 veces más rápido para longitudes de patrón grandes.