public inbox for [email protected]
help / color / mirror / Atom feedFrom: Andy Fan <[email protected]>
Subject: [PATCH v20260912 1/4] Refactor float8out_internval for better performance
Date: Wed, 11 Sep 2024 12:19:57 +0800
Some users like cube, geo needs calls float8out_internval to get a
string, and then copy them into its own StringInfo. In this commit,
we would let the user provide a buffer to float8out_internal so that it
can put the data to buffer directly. This commit also reuse the existing
string length to avoid another strlen call in appendStringInfoString.
---
contrib/cube/cube.c | 17 +++++++++++++++--
src/backend/utils/adt/float.c | 14 ++++++++------
src/backend/utils/adt/geo_ops.c | 34 ++++++++++++++++++++++-----------
src/include/catalog/pg_type.h | 1 +
src/include/utils/float.h | 2 +-
5 files changed, 48 insertions(+), 20 deletions(-)
diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c
index 77263ab277f..a143690092b 100644
--- a/contrib/cube/cube.c
+++ b/contrib/cube/cube.c
@@ -12,6 +12,7 @@
#include "access/gist.h"
#include "access/stratnum.h"
+#include "catalog/pg_type.h"
#include "cubedata.h"
#include "libpq/pqformat.h"
#include "utils/array.h"
@@ -299,26 +300,38 @@ cube_out(PG_FUNCTION_ARGS)
StringInfoData buf;
int dim = DIM(cube);
int i;
+ int str_len;
initStringInfo(&buf);
appendStringInfoChar(&buf, '(');
+
+ /* 3 for ", " and 1 for '\0'. */
+ enlargeStringInfo(&buf, (MAXFLOAT8LEN + 4) * dim);
for (i = 0; i < dim; i++)
{
if (i > 0)
appendStringInfoString(&buf, ", ");
- appendStringInfoString(&buf, float8out_internal(LL_COORD(cube, i)));
+ float8out_internal(LL_COORD(cube, i), buf.data + buf.len, &str_len);
+ buf.len += str_len;
+ buf.data[buf.len] = '\0';
}
appendStringInfoChar(&buf, ')');
if (!cube_is_point_internal(cube))
{
appendStringInfoString(&buf, ",(");
+
+ /* 3 for ", " and 1 for '\0'. */
+ enlargeStringInfo(&buf, (MAXFLOAT8LEN + 4) * dim);
for (i = 0; i < dim; i++)
{
if (i > 0)
appendStringInfoString(&buf, ", ");
- appendStringInfoString(&buf, float8out_internal(UR_COORD(cube, i)));
+
+ float8out_internal(UR_COORD(cube, i), buf.data + buf.len, &str_len);
+ buf.len += str_len;
+ buf.data[buf.len] = '\0';
}
appendStringInfoChar(&buf, ')');
}
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index 362c29ab803..13ceade129e 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -571,22 +571,24 @@ float8out(PG_FUNCTION_ARGS)
* float8out_internal - guts of float8out()
*
* This is exposed for use by functions that want a reasonably
- * platform-independent way of outputting doubles.
- * The result is always palloc'd.
+ * platform-independent way of outputting doubles, output the
+ * string length to *len;
*/
char *
-float8out_internal(double num)
+float8out_internal(double num, char *ascii, int *len)
{
- char *ascii = (char *) palloc(32);
int ndig = DBL_DIG + extra_float_digits;
+ if (ascii == NULL)
+ ascii = (char *) palloc(MAXFLOAT8LEN);
+
if (extra_float_digits > 0)
{
- double_to_shortest_decimal_buf(num, ascii);
+ *len = double_to_shortest_decimal_buf(num, ascii);
return ascii;
}
- (void) pg_strfromd(ascii, 32, ndig, num);
+ *len = pg_strfromd(ascii, 32, ndig, num);
return ascii;
}
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index cc5ce013d0f..212faf08a50 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -29,6 +29,7 @@
#include <float.h>
#include <ctype.h>
+#include "catalog/pg_type.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "nodes/miscnodes.h"
@@ -203,10 +204,12 @@ single_decode(char *num, float8 *x, char **endptr_p,
static void
single_encode(float8 x, StringInfo str)
{
- char *xstr = float8out_internal(x);
+ int str_len;
+ enlargeStringInfo(str, MAXFLOAT8LEN + 1);
+ float8out_internal(x, str->data + str->len, &str_len);
- appendStringInfoString(str, xstr);
- pfree(xstr);
+ str->len += str_len;
+ str->data[str->len] = '\0';
} /* single_encode() */
static bool
@@ -255,12 +258,20 @@ fail:
static void
pair_encode(float8 x, float8 y, StringInfo str)
{
- char *xstr = float8out_internal(x);
- char *ystr = float8out_internal(y);
+ int data_len;
+ /* the additional 2 is for ',' and '\0' */
+ enlargeStringInfo(str, MAXFLOAT8LEN * 2 + 2);
- appendStringInfo(str, "%s,%s", xstr, ystr);
- pfree(xstr);
- pfree(ystr);
+ float8out_internal(x, str->data + str->len, &data_len);
+ str->len += data_len;
+
+ str->data[str->len] = ',';
+ str->len++;
+
+ float8out_internal(y, str->data + str->len, &data_len);
+ str->len += data_len;
+
+ str->data[str->len] = '\0';
}
static bool
@@ -1041,9 +1052,10 @@ Datum
line_out(PG_FUNCTION_ARGS)
{
LINE *line = PG_GETARG_LINE_P(0);
- char *astr = float8out_internal(line->A);
- char *bstr = float8out_internal(line->B);
- char *cstr = float8out_internal(line->C);
+ int datalen;
+ char *astr = float8out_internal(line->A, NULL, &datalen);
+ char *bstr = float8out_internal(line->B, NULL, &datalen);
+ char *cstr = float8out_internal(line->C, NULL, &datalen);
PG_RETURN_CSTRING(psprintf("%c%s%c%s%c%s%c", LDELIM_L, astr, DELIM, bstr,
DELIM, cstr, RDELIM_L));
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 74183ec5a2e..b3858188131 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -348,6 +348,7 @@ MAKE_SYSCACHE(TYPENAMENSP, pg_type_typname_nsp_index, 64);
#endif /* EXPOSE_TO_CLIENT_CODE */
+#define MAXFLOAT8LEN 32
extern ObjectAddress TypeShellMake(const char *typeName,
Oid typeNamespace,
diff --git a/src/include/utils/float.h b/src/include/utils/float.h
index ffa743d6273..69661a7071f 100644
--- a/src/include/utils/float.h
+++ b/src/include/utils/float.h
@@ -43,7 +43,7 @@ extern float8 float8in_internal(char *num, char **endptr_p,
extern float4 float4in_internal(char *num, char **endptr_p,
const char *type_name, const char *orig_string,
struct Node *escontext);
-extern char *float8out_internal(float8 num);
+extern char *float8out_internal(float8 num, char *ascii, int *len);
extern int float4_cmp_internal(float4 a, float4 b);
extern int float8_cmp_internal(float8 a, float8 b);
--
2.43.0
--=-=-=
Content-Type: text/x-diff
Content-Disposition: attachment;
filename=v20260912-0002-Continue-to-remove-some-unnecesary-strlen-.patch
view thread (2+ messages)
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH v20260912 1/4] Refactor float8out_internval for better performance
In-Reply-To: <no-message-id-77783@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox