andygrove opened a new pull request, #5130:
URL: https://github.com/apache/datafusion-comet/pull/5130

   ## Which issue does this PR close?
   
   Part of #5128 (first "High impact" item: string to timestamp / timestamp_ntz 
double regex matching).
   
   ## Rationale for this change
   
   Optimize existing expression.
   
   `timestamp_parser` ORed `is_match` across 14 regex patterns just to decide 
whether the value
   already matched a base shape (so that an offset suffix must not be 
stripped), and then
   `timestamp_parser_with_tz` re-matched the same 14 patterns sequentially to 
pick the parse
   routine — up to 28 regex executions per row. `timestamp_ntz_parser` matched 
three separate
   times (7 time-only + 7 date + 7 in the inner parse), for up to 21 per row.
   
   ## What changes are included in this PR?
   
   Classify the input shape **once** into a `TimestampPattern` and thread that 
single result
   through every decision that previously re-matched.
   
   ASCII input — effectively all real data — is classified by one left-to-right 
byte scan, the
   same technique as the already-tuned `date_parser`. The 14 patterns are 
digit-count and
   separator shapes, so the scan is a direct transcription of them, including 
the two
   asymmetries that are easy to lose: a bare year takes 4-6 digits while a 
separated year takes
   4-7, and a trailing hour takes 1-2 digits while an hour followed by a minute 
must be exactly 2.
   
   Non-ASCII input keeps regex semantics rather than the byte scan: the `regex` 
crate's `\d` is
   Unicode-aware, so the patterns accept non-ASCII digits (e.g. Arabic-Indic) 
that an ASCII scan
   does not. Those inputs go through a single `RegexSet` pass instead of the 
sequential scans, so
   that path gets faster too without any behavior change.
   
   Also removes the seven single-line `parse_str_to_*_timestamp` wrappers, 
which existed only to
   be function pointers in the pattern table.
   
   ## How are these changes tested?
   
   Existing tests — the full `datafusion-comet-spark-expr` suite (540 tests) and
   `CometCastSuite` (162 succeeded, 0 failed, 9 ignored, on the Spark 4.1 
profile so the
   `is_spark4_plus` leading-whitespace path is covered).
   
   Two new tests pin the classifier:
   
   - `test_timestamp_pattern_classifier_matches_regexes` — a differential test 
comparing the
     classifier against a sequential scan of the original patterns over an 
exhaustive
     enumeration of every string of up to 5 shape characters (`019-:.T +`), 
plus every
     one-character deletion, substitution, and insertion applied to nine 
realistic timestamp
     strings, plus non-ASCII inputs. Verified to fail if the classifier is 
perturbed (widening
     the bare-year digit range to 4-7 makes it report `"0202001"`).
   - `test_timestamp_pattern_digit_count_asymmetries` — readable anchors for 
the digit-count
     asymmetries above.
   
   ### Benchmark
   
   New benchmark `native/spark-expr/benches/cast_string_to_timestamp.rs` (no 
coverage existed
   for this cast). Baseline captured on unmodified source. Every shape 
improved; nothing
   regressed.
   
   | shape | main | this PR | change |
   | --- | --- | --- | --- |
   | `timestamp/canonical` | 1830.8 µs | 483.4 µs | **-73.6%** (3.79x) |
   | `timestamp/microseconds` | 2238.4 µs | 576.9 µs | **-74.2%** (3.88x) |
   | `timestamp/date_only` | 890.0 µs | 334.0 µs | **-62.5%** (2.66x) |
   | `timestamp/time_only` | 2271.3 µs | 1198.2 µs | **-47.2%** (1.90x) |
   | `timestamp/iso_z_suffix` | 2896.2 µs | 1127.8 µs | **-61.1%** (2.57x) |
   | `timestamp/named_tz_suffix` | 4380.9 µs | 2574.8 µs | **-41.2%** (1.70x) |
   | `timestamp/invalid` | 2566.4 µs | 993.8 µs | **-61.3%** (2.58x) |
   | `timestamp/sparse_nulls` | 1740.7 µs | 465.2 µs | **-73.3%** (3.74x) |
   | `timestamp/dense_nulls` | 203.2 µs | 68.4 µs | **-66.3%** (2.97x) |
   | `timestamp/non_ascii_digits` | 1045.1 µs | 709.6 µs | **-32.1%** (1.47x) |
   | `timestamp/mixed` | 1805.1 µs | 598.3 µs | **-66.9%** (3.02x) |
   | `timestamp_named_zone/canonical` | 2082.2 µs | 722.4 µs | **-65.3%** 
(2.88x) |
   | `timestamp_ntz/canonical` | 2271.3 µs | 406.6 µs | **-82.1%** (5.59x) |
   | `timestamp_ntz/microseconds` | 2692.6 µs | 508.0 µs | **-81.1%** (5.30x) |
   | `timestamp_ntz/date_only` | 1352.8 µs | 263.3 µs | **-80.5%** (5.14x) |
   | `timestamp_ntz/iso_z_suffix` | 2838.5 µs | 1065.2 µs | **-62.5%** (2.66x) |
   | `timestamp_ntz/invalid` | 2096.8 µs | 975.1 µs | **-53.5%** (2.15x) |
   | `timestamp_ntz/dense_nulls` | 247.8 µs | 61.4 µs | **-75.2%** (4.03x) |
   | `timestamp_ntz/mixed` | 2045.5 µs | 530.7 µs | **-74.1%** (3.85x) |
   
   All 19 shapes reported `Performance has improved.` at p = 0.00.
   
   ## Are there any user-facing changes?
   
   No. Output is bit-identical: same values, same null buffer, same ANSI error 
text.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to