Commit 07f9f4d4 authored by Tom Lane's avatar Tom Lane

Tweak OpernameGetCandidates() to reduce palloc overhead --- profiling

showed that for common operator names such as '=', the pallocs done by
this routine occupied a surprisingly large fraction of the total time
for the parser to process an operator.
parent 21b3c0e0
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.60 2003/12/12 18:45:08 petere Exp $ * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.61 2003/12/29 21:33:09 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -659,6 +659,8 @@ FuncCandidateList ...@@ -659,6 +659,8 @@ FuncCandidateList
OpernameGetCandidates(List *names, char oprkind) OpernameGetCandidates(List *names, char oprkind)
{ {
FuncCandidateList resultList = NULL; FuncCandidateList resultList = NULL;
char *resultSpace = NULL;
int nextResult = 0;
char *schemaname; char *schemaname;
char *opername; char *opername;
Oid namespaceId; Oid namespaceId;
...@@ -685,6 +687,20 @@ OpernameGetCandidates(List *names, char oprkind) ...@@ -685,6 +687,20 @@ OpernameGetCandidates(List *names, char oprkind)
CStringGetDatum(opername), CStringGetDatum(opername),
0, 0, 0); 0, 0, 0);
/*
* In typical scenarios, most if not all of the operators found by the
* catcache search will end up getting returned; and there can be quite
* a few, for common operator names such as '=' or '+'. To reduce the
* time spent in palloc, we allocate the result space as an array large
* enough to hold all the operators. The original coding of this routine
* did a separate palloc for each operator, but profiling revealed that
* the pallocs used an unreasonably large fraction of parsing time.
*/
#define SPACE_PER_OP MAXALIGN(sizeof(struct _FuncCandidateList) + sizeof(Oid))
if (catlist->n_members > 0)
resultSpace = palloc(catlist->n_members * SPACE_PER_OP);
for (i = 0; i < catlist->n_members; i++) for (i = 0; i < catlist->n_members; i++)
{ {
HeapTuple opertup = &catlist->members[i]->tuple; HeapTuple opertup = &catlist->members[i]->tuple;
...@@ -768,8 +784,9 @@ OpernameGetCandidates(List *names, char oprkind) ...@@ -768,8 +784,9 @@ OpernameGetCandidates(List *names, char oprkind)
/* /*
* Okay to add it to result list * Okay to add it to result list
*/ */
newResult = (FuncCandidateList) newResult = (FuncCandidateList) (resultSpace + nextResult);
palloc(sizeof(struct _FuncCandidateList) + sizeof(Oid)); nextResult += SPACE_PER_OP;
newResult->pathpos = pathpos; newResult->pathpos = pathpos;
newResult->oid = HeapTupleGetOid(opertup); newResult->oid = HeapTupleGetOid(opertup);
newResult->nargs = 2; newResult->nargs = 2;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment