print_number: Introduce fast path for integers.

Thanks @Tangerino for suggesting this optimisation.
This commit is contained in:
Max Bruckner 2018-01-29 20:24:42 +01:00
parent cfee6a7318
commit a2ede77ee0

15
cJSON.c
View File

@ -466,7 +466,8 @@ static void update_offset(printbuffer * const buffer)
static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
{ {
unsigned char *output_pointer = NULL; unsigned char *output_pointer = NULL;
double d = item->valuedouble; double number = item->valuedouble;
int integer = double_to_saturated_integer(number);
int length = 0; int length = 0;
size_t i = 0; size_t i = 0;
unsigned char number_buffer[26]; /* temporary buffer to print the number into */ unsigned char number_buffer[26]; /* temporary buffer to print the number into */
@ -478,20 +479,24 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
return false; return false;
} }
if (is_nan(d) || is_infinity(d)) if (is_nan(number) || is_infinity(number))
{ {
length = sprintf((char*)number_buffer, "null"); length = sprintf((char*)number_buffer, "null");
} }
else if (number == integer) /* avoid overhead for integers */
{
length = sprintf((char*)number_buffer, "%d", integer);
}
else else
{ {
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
length = sprintf((char*)number_buffer, "%1.15g", d); length = sprintf((char*)number_buffer, "%1.15g", number);
/* Check whether the original double can be recovered */ /* Check whether the original double can be recovered */
if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d)) if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != number))
{ {
/* If not, print with 17 decimal places of precision */ /* If not, print with 17 decimal places of precision */
length = sprintf((char*)number_buffer, "%1.17g", d); length = sprintf((char*)number_buffer, "%1.17g", number);
} }
} }