diff options
author | Neil Conway <neilc@samurai.com> | 2005-04-06 23:56:07 +0000 |
---|---|---|
committer | Neil Conway <neilc@samurai.com> | 2005-04-06 23:56:07 +0000 |
commit | be2f825d51176bd21a627a529476f94de5bad4c2 (patch) | |
tree | 72f9ceb6d1da0fbb10dcfd7355e70b5797ce4b28 /src/backend/utils/adt/float.c | |
parent | a6bbfedcf7a899c91182f373f93f15f5af247647 (diff) | |
download | postgresql-be2f825d51176bd21a627a529476f94de5bad4c2.tar.gz postgresql-be2f825d51176bd21a627a529476f94de5bad4c2.zip |
Apply the "nodeAgg" optimization to more of the builtin transition
functions. This patch optimizes int2_sum(), int4_sum(), float4_accum()
and float8_accum() to avoid needing to copy the transition function's
state for each input tuple of the aggregate. In an extreme case
(e.g. SELECT sum(int2_col) FROM table where table has a single column),
it improves performance by about 20%. For more complex queries or tables
with wider rows, the relative performance improvement will not be as
significant.
Diffstat (limited to 'src/backend/utils/adt/float.c')
-rw-r--r-- | src/backend/utils/adt/float.c | 74 |
1 files changed, 55 insertions, 19 deletions
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index e51babfebfb..c943ee2c71d 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.113 2005/02/11 04:08:58 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.114 2005/04/06 23:56:07 neilc Exp $ * *------------------------------------------------------------------------- */ @@ -1902,8 +1902,6 @@ float8_accum(PG_FUNCTION_ARGS) float8 N, sumX, sumX2; - Datum transdatums[3]; - ArrayType *result; transvalues = check_float8_array(transarray, "float8_accum"); N = transvalues[0]; @@ -1914,15 +1912,35 @@ float8_accum(PG_FUNCTION_ARGS) sumX += newval; sumX2 += newval * newval; - transdatums[0] = Float8GetDatumFast(N); - transdatums[1] = Float8GetDatumFast(sumX); - transdatums[2] = Float8GetDatumFast(sumX2); + /* + * If we're invoked by nodeAgg, we can cheat and modify our first + * parameter in-place to reduce palloc overhead. Otherwise we + * construct a new array with the updated transition data and + * return it. + */ + if (fcinfo->context && IsA(fcinfo->context, AggState)) + { + transvalues[0] = N; + transvalues[1] = sumX; + transvalues[2] = sumX2; - result = construct_array(transdatums, 3, - FLOAT8OID, - sizeof(float8), false /* float8 byval */ , 'd'); + PG_RETURN_ARRAYTYPE_P(transarray); + } + else + { + Datum transdatums[3]; + ArrayType *result; + + transdatums[0] = Float8GetDatumFast(N); + transdatums[1] = Float8GetDatumFast(sumX); + transdatums[2] = Float8GetDatumFast(sumX2); - PG_RETURN_ARRAYTYPE_P(result); + result = construct_array(transdatums, 3, + FLOAT8OID, + sizeof(float8), false /* float8 byval */ , 'd'); + + PG_RETURN_ARRAYTYPE_P(result); + } } Datum @@ -1935,8 +1953,6 @@ float4_accum(PG_FUNCTION_ARGS) sumX, sumX2, newval; - Datum transdatums[3]; - ArrayType *result; transvalues = check_float8_array(transarray, "float4_accum"); N = transvalues[0]; @@ -1950,15 +1966,35 @@ float4_accum(PG_FUNCTION_ARGS) sumX += newval; sumX2 += newval * newval; - transdatums[0] = Float8GetDatumFast(N); - transdatums[1] = Float8GetDatumFast(sumX); - transdatums[2] = Float8GetDatumFast(sumX2); + /* + * If we're invoked by nodeAgg, we can cheat and modify our first + * parameter in-place to reduce palloc overhead. Otherwise we + * construct a new array with the updated transition data and + * return it. + */ + if (fcinfo->context && IsA(fcinfo->context, AggState)) + { + transvalues[0] = N; + transvalues[1] = sumX; + transvalues[2] = sumX2; - result = construct_array(transdatums, 3, - FLOAT8OID, - sizeof(float8), false /* float8 byval */ , 'd'); + PG_RETURN_ARRAYTYPE_P(transarray); + } + else + { + Datum transdatums[3]; + ArrayType *result; + + transdatums[0] = Float8GetDatumFast(N); + transdatums[1] = Float8GetDatumFast(sumX); + transdatums[2] = Float8GetDatumFast(sumX2); - PG_RETURN_ARRAYTYPE_P(result); + result = construct_array(transdatums, 3, + FLOAT8OID, + sizeof(float8), false /* float8 byval */ , 'd'); + + PG_RETURN_ARRAYTYPE_P(result); + } } Datum |