Skip to content

Commit cef78ba

Browse files
committed
Optimize value_stringToDouble()
1 parent a1b10ad commit cef78ba

File tree

1 file changed

+53
-23
lines changed

1 file changed

+53
-23
lines changed

src/scratch/value_functions_p.h

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,41 @@ inline bool value_isNegativeInf(T v)
5353
extern "C"
5454
{
5555

56+
inline long value_convert_int_str(const char *str, int n, bool *ok)
57+
{
58+
if (ok)
59+
*ok = false;
60+
61+
const char *begin = str;
62+
const char *end = begin + n;
63+
64+
bool isNegative = false;
65+
long ret = 0;
66+
67+
if (*str == '-' || *str == '+') {
68+
isNegative = (*str == '-');
69+
++str;
70+
71+
if (str == begin + n)
72+
return 0;
73+
}
74+
75+
while (str < end) {
76+
if (*str < '0' || *str > '9')
77+
return 0;
78+
79+
ret = ret * 10 + (*str++ - '0');
80+
}
81+
82+
if (ok)
83+
*ok = true;
84+
85+
if (isNegative)
86+
return -ret;
87+
else
88+
return ret;
89+
}
90+
5691
inline size_t value_getSize(size_t x)
5792
{
5893
if (x == 0)
@@ -197,44 +232,40 @@ extern "C"
197232
if (ok)
198233
*ok = false;
199234

200-
const size_t len = strlen(s);
201-
202-
if (strlen(s) == 0) {
235+
if (!s || *s == '\0') {
203236
if (ok)
204237
*ok = true;
205238

206239
return 0;
207240
}
208241

242+
const size_t len = strlen(s);
209243
const char *begin = s;
210-
const char *strEnd = s + len;
211-
const char *end = strEnd;
244+
const char *end = s + len;
212245

213246
// Trim leading spaces
214247
while (begin < end && IS_SPACE(*begin))
215248
++begin;
216249

217-
end = begin + 1;
218-
219250
// Trim trailing spaces
220-
while (end < strEnd && !IS_SPACE(*(end)))
221-
++end;
222-
223-
// Only whitespace can be after the end
224-
const char *p = end;
251+
while (end > begin && IS_SPACE(*(end - 1)))
252+
--end;
225253

226-
while (p < strEnd) {
227-
if (!IS_SPACE(*p))
228-
return 0;
229-
230-
p++;
254+
if (begin == end) { // All spaces case
255+
if (ok)
256+
*ok = true;
257+
return 0.0;
231258
}
232259

233-
if (end - begin <= 0 || end > strEnd) {
260+
// Try to convert integer early
261+
bool isInt = false;
262+
double ret = value_convert_int_str(begin, end - begin, &isInt);
263+
264+
if (isInt) {
234265
if (ok)
235266
*ok = true;
236267

237-
return 0;
268+
return ret;
238269
}
239270

240271
char *copy = nullptr;
@@ -315,7 +346,6 @@ extern "C"
315346
return 0;
316347
}
317348

318-
double ret = 0;
319349
auto [ptr, ec] = fast_float::from_chars(begin, end, ret, fast_float::chars_format::json);
320350

321351
if (copy)
@@ -330,15 +360,15 @@ extern "C"
330360
return 0;
331361

332362
// Special values
333-
if (strcmp(s, "Infinity") == 0) {
363+
if (strncmp(s, "Infinity", len) == 0) {
334364
if (ok)
335365
*ok = true;
336366
return std::numeric_limits<double>::infinity();
337-
} else if (strcmp(s, "-Infinity") == 0) {
367+
} else if (strncmp(s, "-Infinity", len) == 0) {
338368
if (ok)
339369
*ok = true;
340370
return -std::numeric_limits<double>::infinity();
341-
} else if (strcmp(s, "NaN") == 0) {
371+
} else if (strncmp(s, "NaN", len) == 0) {
342372
if (ok)
343373
*ok = true;
344374
return std::numeric_limits<double>::quiet_NaN();

0 commit comments

Comments
 (0)