[ 
https://issues.apache.org/jira/browse/SPARK-59968?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

ASF GitHub Bot updated SPARK-59968:
-----------------------------------
    Labels: pull-request-available  (was: )

> Reuse the regex Matcher across rows in LIKE and RLIKE codegen
> -------------------------------------------------------------
>
>                 Key: SPARK-59968
>                 URL: https://issues.apache.org/jira/browse/SPARK-59968
>             Project: Spark
>          Issue Type: Improvement
>          Components: SQL
>    Affects Versions: 4.2.0
>            Reporter: David Mollitor
>            Priority: Minor
>              Labels: pull-request-available
>
> h3. Problem
> When the pattern of {{RLIKE}} or {{LIKE}} is foldable, the generated code 
> compiles the {{java.util.regex.Pattern}} once and keeps it in mutable state. 
> However, it still calls {{pattern.matcher(input)}} on every row:
> {code:java}
> value = patternRLike.matcher(input.toString()).find(0);
> {code}
> Each call allocates a new {{java.util.regex.Matcher}} along with its internal 
> {{{}groups{}}}, {{locals}} and {{localsPos}} arrays. The JIT cannot 
> scalar-replace this allocation because the Matcher escapes into the regex 
> engine's recursive {{Node.match}} graph. Allocation profiles of a filter 
> using a token-boundary {{RLIKE}}  show {{Matcher.<init>}} <- 
> {{Pattern.matcher}} <- generated {{processNext}} at roughly 2-5% of allocated 
> bytes.
> {{LIKE}} has the same shape (using {{{}matches(){}}}) for patterns that 
> {{LikeSimplification}} does not rewrite into {{StartsWith}} / {{EndsWith}} / 
> {{{}Contains{}}}, such as {{{}a%b%c{}}}.
> h3. Proposal
> In the foldable branch of {{RLike.doGenCode}} and {{{}Like.doGenCode{}}}, 
> build the {{Matcher}} once in the mutable state's init code, and reset it per 
> row instead of allocating a new one:
> {code:java}
> // init
> matcherRLike = java.util.regex.Pattern.compile("<regex>", 
> <flags>).matcher("");
> // per row
> value = matcherRLike.reset(input.toString()).find(0);
> {code}
>  * The Matcher replaces the Pattern field (the Matcher holds its Pattern), so 
> the number of mutable states does not change.
>  * Codegen mutable state is per generated-object instance, so the Matcher is 
> never shared across threads.
>  * Results are unchanged; {{find(0)}} / {{matches()}} keep the same semantics 
> as the interpreted path.
> Out of scope: the interpreted path (RLike/Like are not {{{}stateful{}}}), 
> non-foldable patterns, LIKE ANY / LIKE ALL, and the per-row 
> {{UTF8String.toString()}} conversion.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to