Merge pull request #7883 from corleypc/strconv-fast-float-swar

Moves SWAR floats parsing behind the STRCONV_FAST_FLOAT #config
This commit is contained in:
Jeroen van Rijn authored and GitHub committed 2026-10-11 07:57:12 -07:00
commit 7e2e348b4b
3 files changed
+54 -44

No files matched your search

+4 -2
View File
@@ -28,7 +28,7 @@ _ :: bits // needed for STRCONV_FAST_FLOAT=false
/*
Disable with `-define:STRCONV_FAST_FLOAT=false` to drop the Eisel-Lemire step
and its table.
and its table, and to read digits one at a time (instead of eight).
*/
FAST_FLOAT :: #config(STRCONV_FAST_FLOAT, true)
@@ -183,7 +183,9 @@ parse_number_string :: #force_inline proc "contextless" (s: string) -> (mantissa
if i < n && s[i] == '.' {
i += 1
frac_start := i
i, mantissa = loop_parse_if_eight_digits(s, i, mantissa)
when FAST_FLOAT {
i, mantissa = loop_parse_if_eight_digits(s, i, mantissa)
}
for i < n && s[i] - '0' <= 9 {
mantissa = mantissa*10 + u64(s[i] - '0')
i += 1
+31 -27
View File
@@ -36,15 +36,17 @@ scan_hex_float :: proc "contextless" (s: string) -> (mantissa: u64, exp: int, ne
saw_digits ||= s[i] == '0'
i += 1
}
for i+8 <= n && nd+8 <= MAX_HEX_DIGITS {
v := read8_to_u64(s, i)
if !is_eight_hex_digits(v) {
break
when FAST_FLOAT {
for i+8 <= n && nd+8 <= MAX_HEX_DIGITS {
v := read8_to_u64(s, i)
if !is_eight_hex_digits(v) {
break
}
mantissa = mantissa<<32 | parse_eight_hex_digits(v)
nd += 8
i += 8
saw_digits = true
}
mantissa = mantissa<<32 | parse_eight_hex_digits(v)
nd += 8
i += 8
saw_digits = true
}
for i < n {
d := hex_digit_table[s[i]]
@@ -76,27 +78,29 @@ scan_hex_float :: proc "contextless" (s: string) -> (mantissa: u64, exp: int, ne
i += 1
}
}
for i+8 <= n && nd+8 <= MAX_HEX_DIGITS {
v := read8_to_u64(s, i)
if !is_eight_hex_digits(v) {
break
}
mantissa = mantissa<<32 | parse_eight_hex_digits(v)
nd += 8
exp -= 32
i += 8
saw_digits = true
}
if i+4 <= n && nd+4 <= MAX_HEX_DIGITS {
// Four digits: pad them with "0000" and use the 8-digit code.
v := u64(read4_to_u32(s, i)) | 0x3030_3030 << 32
if is_eight_hex_digits(v) {
mantissa = mantissa<<16 | parse_eight_hex_digits(v) >> 16
nd += 4
exp -= 16
i += 4
when FAST_FLOAT {
for i+8 <= n && nd+8 <= MAX_HEX_DIGITS {
v := read8_to_u64(s, i)
if !is_eight_hex_digits(v) {
break
}
mantissa = mantissa<<32 | parse_eight_hex_digits(v)
nd += 8
exp -= 32
i += 8
saw_digits = true
}
if i+4 <= n && nd+4 <= MAX_HEX_DIGITS {
// Four digits: pad them with "0000" and use the 8-digit code.
v := u64(read4_to_u32(s, i)) | 0x3030_3030 << 32
if is_eight_hex_digits(v) {
mantissa = mantissa<<16 | parse_eight_hex_digits(v) >> 16
nd += 4
exp -= 16
i += 4
saw_digits = true
}
}
}
for i < n {
d := hex_digit_table[s[i]]
+19 -15
View File
@@ -974,24 +974,28 @@ parse_float_prefix_generic :: proc($T: typeid, str: string) -> (value: T, nr: in
i := 2
// Read 8 hex digits at a time, then 4 digits at a time (like "0h3c00" or groups
// between `_` separators), then single digits and `_` separators.
for i+8 <= len(str) {
v := read8_to_u64(str, i)
if !is_eight_hex_digits(v) {
break
when FAST_FLOAT {
for i+8 <= len(str) {
v := read8_to_u64(str, i)
if !is_eight_hex_digits(v) {
break
}
as_int = as_int<<32 | parse_eight_hex_digits(v)
digits += 8
i += 8
}
as_int = as_int<<32 | parse_eight_hex_digits(v)
digits += 8
i += 8
}
for i < len(str) {
if i+4 <= len(str) {
// Four digits: pad them with "0000" and use the 8-digit code.
v := u64(read4_to_u32(str, i)) | 0x3030_3030 << 32
if is_eight_hex_digits(v) {
as_int = as_int<<16 | parse_eight_hex_digits(v) >> 16
digits += 4
i += 4
continue
when FAST_FLOAT {
if i+4 <= len(str) {
// Four digits: pad them with "0000" and use the 8-digit code.
v := u64(read4_to_u32(str, i)) | 0x3030_3030 << 32
if is_eight_hex_digits(v) {
as_int = as_int<<16 | parse_eight_hex_digits(v) >> 16
digits += 4
i += 4
continue
}
}
}
if str[i] != '_' {