Skip to content

Commit

Permalink
Optimize array creation in vectorized aggregate functions (#7460)
Browse files Browse the repository at this point in the history
We can inline the few lines of code required to create an array, instead
of calling the very generic `construct_array` function which shows up in
profiles.
  • Loading branch information
akuzm authored Nov 21, 2024
1 parent c0353d8 commit f88488a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 20 deletions.
33 changes: 19 additions & 14 deletions tsl/src/nodes/vector_agg/function/float48_accum_single.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,27 +69,32 @@ FUNCTION_NAME(emit)(void *agg_state, Datum *out_result, bool *out_isnull)
{
FUNCTION_NAME(state) *state = (FUNCTION_NAME(state) *) agg_state;

Datum transdatums[3] = {
Float8GetDatumFast(state->N),
Float8GetDatumFast(state->Sx),
const size_t nbytes = 3 * sizeof(float8) + ARR_OVERHEAD_NONULLS(/* ndims = */ 1);
ArrayType *result = palloc(nbytes);
SET_VARSIZE(result, nbytes);
result->ndim = 1;
result->dataoffset = 0;
result->elemtype = FLOAT8OID;
ARR_DIMS(result)[0] = 3;
ARR_LBOUND(result)[0] = 1;

/*
* The array elements are stored by value, regardless of if the float8
* itself is by-value on this platform.
*/
((float8 *) ARR_DATA_PTR(result))[0] = state->N;
((float8 *) ARR_DATA_PTR(result))[1] = state->Sx;
((float8 *) ARR_DATA_PTR(result))[2] =
/*
* Sxx should be NaN if any of the inputs are infinite or NaN. This is
* checked by float8_combine even if it's not used for the actual
* calculations.
*/
Float8GetDatum(0. * state->Sx
0. * state->Sx
#ifdef NEED_SXX
+ state->Sxx
+ state->Sxx
#endif
),
};

ArrayType *result = construct_array(transdatums,
3,
FLOAT8OID,
sizeof(float8),
FLOAT8PASSBYVAL,
TYPALIGN_DOUBLE);
;

*out_result = PointerGetDatum(result);
*out_isnull = false;
Expand Down
21 changes: 15 additions & 6 deletions tsl/src/nodes/vector_agg/function/int24_avg_accum_templates.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,22 @@ int24_avg_accum_emit(void *agg_state, Datum *out_result, bool *out_isnull)
{
Int24AvgAccumState *state = (Int24AvgAccumState *) agg_state;

Datum transdatums[2] = {
Int64GetDatumFast(state->count),
Int64GetDatumFast(state->sum),
};
const size_t nbytes = 2 * sizeof(int64) + ARR_OVERHEAD_NONULLS(/* ndims = */ 1);
ArrayType *result = palloc(nbytes);
SET_VARSIZE(result, nbytes);
result->ndim = 1;
result->dataoffset = 0;
result->elemtype = INT8OID;
ARR_DIMS(result)[0] = 2;
ARR_LBOUND(result)[0] = 1;

/*
* The array elements are stored by value, regardless of if the int8 itself
* is by-value on this platform.
*/
((int64 *) ARR_DATA_PTR(result))[0] = state->count;
((int64 *) ARR_DATA_PTR(result))[1] = state->sum;

ArrayType *result =
construct_array(transdatums, 2, INT8OID, sizeof(int64), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
*out_result = PointerGetDatum(result);
*out_isnull = false;
}
Expand Down

0 comments on commit f88488a

Please sign in to comment.