FunctionCallN improvement. - Mailing list pgsql-hackers

From a_ogawa
Subject FunctionCallN improvement.
Date
Msg-id PIEMIKOOMKNIJLLLBCBBIEIOCEAA.a_ogawa@hi-ho.ne.jp
Whole thread Raw
Responses Re: FunctionCallN improvement.  (Neil Conway <neilc@samurai.com>)
List pgsql-hackers
When SQL that returns many tuples with character code conversion
is executed, the FunctionCall3/FunctionCall5 becomes a bottleneck.
Because MemSet is used to initialize FunctionCallInfoData in these
functions, a lot of cycles are spent. 

<test query>
set client_encoding to 'SJIS';
select * from pg_class, pg_amop;
(This SQL is used only to get a lot of tuples, and there is no 
logical meaning) 

<result of profile>
Each sample counts as 0.01 seconds. %   cumulative   self              self     totaltime   seconds   seconds    calls
s/call   s/call  name22.91      1.29     1.29  1562351     0.00     0.00  FunctionCall518.29      2.32     1.03
1602006    0.00     0.00  FunctionCall3 5.06      2.60     0.28  4892127     0.00     0.00  AllocSetAlloc 4.88
2.88    0.28  9781322     0.00     0.00  AllocSetFreeIndex 4.35      3.12     0.24  1587600     0.00     0.00
ExecEvalVar

Most of calls of these functions are from printtup. 
FunctionCall3 is used to generate the text. 
FunctionCall5 is used to character code conversion.
(printtup -> pq_sendcountedtext -> pg_server_to_client ->perform_default_encoding_conversion -> FunctionCall5)

I think that we should initialize only the fields of 
FunctionCallInfoData that must be initialized. 
(Such as FunctionCall1)

I have two plans to modify the code. 
(a)Change FunctionCall3/FunctionCall5 like FunctionCall1. It is simple, minimum change.

(b)Define the macro that initialize FunctionCallInfoData, and use it 
instead of MemSet in all FunctionCallN, DirectFunctionCallN, 
OidFunctionCallN.This macro is the following. 

#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs)     \   do {
\      (Fcinfo)->flinfo = Flinfo;                          \       (Fcinfo)->context = NULL;
\      (Fcinfo)->resultinfo = NULL;                        \       (Fcinfo)->isnull = false;
\      (Fcinfo)->nargs = Nargs;                            \       MemSet((Fcinfo)->argnull, 0, Nargs * sizeof(bool));
\  } while(0)
 

I think that plan(b) is better, because source code consistency 
and efficiency improve.

Any comments?

regards, 

---
A.Ogawa ( a_ogawa@hi-ho.ne.jp )



pgsql-hackers by date:

Previous
From: "Mark Cave-Ayland"
Date:
Subject: 7.3.8 under FC3 takes excessive semaphores?
Next
From: Tommi Maekitalo
Date:
Subject: Re: IBM patent