Teach convert() and friends to avoid copying when possible.

Presently, pg_convert() allocates a new bytea and copies the result
regardless of whether any conversion actually happened.  This
commit adjusts this function to return the source pointer as-is if
no conversion occurred.  This optimization isn't expected to make a
tremendous difference, but it still seems worthwhile to avoid
unnecessary memory allocations.

Author: Yurii Rashkovskii
Reviewed-by: Bertrand Drouvot
Discussion: https://postgr.es/m/CA%2BRLCQyknBPSWXRBQGOi6aYEcdQ9RpH9Kch4GjoeY8dQ3D%2Bvhw%40mail.gmail.com
This commit is contained in:
Nathan Bossart 2023-12-04 11:55:18 -06:00
parent e7c6efe305
commit b14b1eb4da

View File

@ -585,19 +585,19 @@ pg_convert(PG_FUNCTION_ARGS)
src_encoding, src_encoding,
dest_encoding); dest_encoding);
/* update len if conversion actually happened */
if (dest_str != src_str) /* return source string if no conversion happened */
len = strlen(dest_str); if (dest_str == src_str)
PG_RETURN_BYTEA_P(string);
/* /*
* build bytea data type structure. * build bytea data type structure.
*/ */
len = strlen(dest_str);
retval = (bytea *) palloc(len + VARHDRSZ); retval = (bytea *) palloc(len + VARHDRSZ);
SET_VARSIZE(retval, len + VARHDRSZ); SET_VARSIZE(retval, len + VARHDRSZ);
memcpy(VARDATA(retval), dest_str, len); memcpy(VARDATA(retval), dest_str, len);
pfree(dest_str);
if (dest_str != src_str)
pfree(dest_str);
/* free memory if allocated by the toaster */ /* free memory if allocated by the toaster */
PG_FREE_IF_COPY(string, 0); PG_FREE_IF_COPY(string, 0);