Skip to content

Commit b86ff49

Browse files
authored
fix: jv_number_value should cache the double value of literal numbers (#3245)
The code of `jv_number_value` is intended to cache the double value of literal numbers, but it does not work because it accepts the `jv` struct by value. This patch fixes the behavior by checking if the double value is `NaN`, which indicates the unconverted value. This patch improves the performance of major use cases; e.g. `range(1000000)` runs 25% faster.
1 parent 64bd8ba commit b86ff49

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

src/jv.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,6 @@ enum {
206206
JVP_NUMBER_DECIMAL = 1
207207
};
208208

209-
#define JV_NUMBER_SIZE_INIT (0)
210-
#define JV_NUMBER_SIZE_CONVERTED (1)
211-
212209
#define JVP_FLAGS_NUMBER_NATIVE JVP_MAKE_FLAGS(JV_KIND_NUMBER, JVP_MAKE_PFLAGS(JVP_NUMBER_NATIVE, 0))
213210
#define JVP_FLAGS_NUMBER_LITERAL JVP_MAKE_FLAGS(JV_KIND_NUMBER, JVP_MAKE_PFLAGS(JVP_NUMBER_DECIMAL, 1))
214211

@@ -587,8 +584,12 @@ static jv jvp_literal_number_new(const char * literal) {
587584
jv_mem_free(n);
588585
return JV_INVALID;
589586
}
587+
if (decNumberIsNaN(&n->num_decimal)) {
588+
jv_mem_free(n);
589+
return jv_number(NAN);
590+
}
590591

591-
jv r = {JVP_FLAGS_NUMBER_LITERAL, 0, 0, JV_NUMBER_SIZE_INIT, {&n->refcnt}};
592+
jv r = {JVP_FLAGS_NUMBER_LITERAL, 0, 0, 0, {&n->refcnt}};
592593
return r;
593594
}
594595

@@ -696,9 +697,8 @@ double jv_number_value(jv j) {
696697
if (JVP_HAS_FLAGS(j, JVP_FLAGS_NUMBER_LITERAL)) {
697698
jvp_literal_number* n = jvp_literal_number_ptr(j);
698699

699-
if (j.size != JV_NUMBER_SIZE_CONVERTED) {
700+
if (isnan(n->num_double)) {
700701
n->num_double = jvp_literal_number_to_double(j);
701-
j.size = JV_NUMBER_SIZE_CONVERTED;
702702
}
703703

704704
return n->num_double;
@@ -729,7 +729,7 @@ int jvp_number_is_nan(jv n) {
729729
return decNumberIsNaN(pdec);
730730
}
731731
#endif
732-
return n.u.number != n.u.number;
732+
return isnan(n.u.number);
733733
}
734734

735735
jv jv_number_negate(jv n) {

0 commit comments

Comments
 (0)