Special case parse in base 10
This PR special cases base 10 integer parsing to speed it up using the Rust stdlib.
Some code I used to test (run locally, I don't have a wasm build)
N ← 1e6
⊃($LongNumsFill ⊙◌⍜now⋕₁₀ ⬚@0 °⋕ ⇡ N
| $LongNumsBoxed ⊙◌⍜now⋕₁₀ °⋕ ⇡ N
| $ShortNumsFill ⊙◌⍜now⋕₁₀ ⬚@0 °⋕ ▽ (÷10 N) ⇡ 10
| $ShortNumsBox ⊙◌⍜now⋕₁₀ °⋕ ▽ (÷10 N) ⇡ 10
)
| Metric | main | PR | Speedup (%) |
|---|---|---|---|
| LongNumsFill | 0.494306 | 0.355260 | 28.13% |
| LongNumsBoxed | 0.626325 | 0.479558 | 23.43% |
| ShortNumsFill | 0.351373 | 0.316105 | 10.04% |
| ShortNumsBox | 0.493949 | 0.447104 | 9.48% |
Note this code parses f64 more accurately than the code that was previously in use, so for some edge cases it would behave differently by a few ULP. Is that acceptable? (What's nice about this is that it now matches the results of using a float literal, since it now rounds correctly)
Example:
⋕₁₀ "3.14159265358979285"
# Before: π
# After: ~π
Specifying π and co to the maximum precision should parse to π.
Specifying
πand co to the maximum precision should parse toπ.
Yeah that's fine, and it does, in the example I gave the string value rounds correctly to nextafter(pi, -inf) but the code currently thinks the value rounds to exactly pi, which it does not.
The only downside is if some code relies on the incorrectly rounded results that are currently calculated.
More examples before/after:
DetectPi ← ⍚(⍣(↙₄|∘)◇⊢pretty)⋕₁₀ °⋕ ↘₁÷ ⇡ 12
≡DetectPi[π τ η]
Before:
┌─
╷ "π"│"η" │"τ/6" │"τ/8" │"0.62"│"τ/12"│"0.44"│"0.39"│"0.34"│"0.31"│"0.28"
───┼─────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────
"τ"│"π" │"τ/3" │"η" │"τ/5" │"τ/6" │"0.89"│"τ/8" │"~τ/9"│"0.62"│"0.57"
───┼─────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────
"η"│"τ/8"│"τ/12"│"0.39"│"0.31"│"0.26"│"0.22"│"0.19"│"0.17"│"0.15"│"0.14"
After:
┌─
╷ "π"│"η" │"τ/6" │"τ/8" │"0.62"│"τ/12"│"0.44"│"0.39"│"0.34"│"0.31"│"0.28"
───┼─────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────
"τ"│"π" │"τ/3" │"η" │"τ/5" │"τ/6" │"0.89"│"τ/8" │"τ/9" │"0.62"│"0.57"
───┼─────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────
"η"│"τ/8"│"τ/12"│"0.39"│"0.31"│"0.26"│"0.22"│"0.19"│"0.17"│"0.15"│"0.14"
┘
So it still parses fractions of pi correctly, but also now can detect them more accurately for edge cases (see the tau/9 case where it now sees it as exactly tau/9 rather than ~tau/9)