pjfanning opened a new pull request, #1437:
URL: https://github.com/apache/poi/pull/1437

   Follow-up to #1436, which fixes the same class of problem in 
`rangeConditionalPattern`.
   
   Repro: `new DataFormatter().formatRawCellContents(1.5, -1, 
"#".repeat(20_000) + "/")`. Any format containing `#/` or `?/` reaches 
`fractionPattern`. The old regex took about 2.5 s on a 5,000-character run of 
`#` and about 28 s on 20,000.
   
   Cause: in `(?:([#\d]+)\s+)?(#+)\s*/\s*([#\d]+)`, `find()` retries from every 
position inside a run of `#` or digits, and each attempt scans to the end of 
the run, so the cost is quadratic.
   
   Fix: `(?:(?<![#\d])([#\d]++)\s+)?(?<!#)(#++)\s*/\s*([#\d]+)`
   - The lookbehinds stop a match from starting inside a run. A match that 
starts after a `#`, or a whole-part group that starts after a `#` or digit, can 
always be extended one character to the left. So `find()` would already have 
returned that earlier match, and the leftmost match is unchanged.
   - The possessive quantifiers only drop backtracking that can't succeed, 
because what follows each run (`\s` or `/`) can't be a `#` or digit.
   
   I compared the old and new patterns on all 1.4M strings up to length 10 
built from `[#1 /]` (the characters left after `fractionStripper`). Start, end 
and all three groups are identical. The new pattern takes a few ms on inputs of 
20,000 to 40,000 characters.
   
   `testFractionWithLongRun` times out after 10 s before the change and passes 
after. `TestDataFormatter`, `TestHSSFDataFormatter`, `TestFractionFormat`, 
`org.apache.poi.ss.format.*`, `TestCellFormatPart`, 
`TestDataFormatterAgainstExcel` and `TestXSSFDataFormat` pass.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


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