David Mollitor created SPARK-59507:
--------------------------------------

             Summary: Parse interval fractional seconds without building a 
padded string in IntervalUtils
                 Key: SPARK-59507
                 URL: https://issues.apache.org/jira/browse/SPARK-59507
             Project: Spark
          Issue Type: Improvement
          Components: SQL
    Affects Versions: 4.1.0
            Reporter: David Mollitor


{{IntervalUtils.parseNanos}} converts the fractional-second digits of a 
day-time interval into nanoseconds by right-padding them to 9 characters with a 
string concatenation and a substring, then parsing the result:
{code:scala}
val alignedStr = if (nanos.length < maxNanosLen) {
  (nanos + "000000000").substring(0, maxNanosLen)
} else nanos
val nanoSecond = toLongWithRange(nanosStr, alignedStr, 0L, 999999999L)
{code}
This allocates two throwaway strings per call – one for the concatenation and 
one for the substring – purely to zero-pad the value before an integer parse.
h3. Proposed change

The fractional part is guaranteed to be 1-9 ASCII digits by the grammar, so the 
value can be parsed directly and scaled by the corresponding power of ten 
instead of building a padded string:
{code:scala}
val raw = toLongWithRange(nanosStr, nanos, 0L, 999999999L)   // 1..9 digits
val nanoSecond = raw * pow10(maxNanosLen - nanos.length)     // e.g. "5" -> 5 * 
1e8
{code}
This removes both string allocations on the fractional-seconds path. The result 
is
identical: {{raw}} is always in {{[0, 999999999]}} and the scaled value stays 
within the
same range, so the range check and error behavior are unchanged. The change 
also folds the {{length == 9}} case in for free ({{{}pow10(0) == 1{}}}).



--
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