Thread: Performance glitch in GetCurrentAbsoluteTime()
I have been doing some profiling this weekend in response to Vadim's challenge to reduce the amount of overhead in a simple INSERT command. I've found a number of simple improvements that I hope to check in shortly. I came across something in the time code that I thought I'd better check with you before changing. In utils/adt/nabstime.c, the function GetCurrentAbsoluteTime() is called during each StartTransaction in order to save the transaction's start time. It shows up unreasonably high in my profile (> 1% of runtime): 0.62 10.22 100001/100001 StartTransaction [65] [91] 1.4 0.62 10.22 100001 GetCurrentAbsoluteTime [91] 0.92 8.30 100001/100001 localtime[105] 0.88 0.00 100001/100004 time [305] 0.12 0.00 100001/104713 strcpy[479] Now the interesting thing about this is that the essential part of the function is just the time() call, AFAICS, and that's quite cheap. More than 90% of the runtime is being spent in the "if (!HasCTZSet)" branch. I see no reason for that code to be run during every single transaction. It sets the following variables: CTimeZoneCDayLightCTZName CDayLight is not used *anywhere* except for debug printouts, and could go away completely. CTZName is not used if USE_POSIX_TIME is defined, which is true on most platforms. CTimeZone is not quite as useless, but there are only a couple places where it's used when USE_POSIX_TIME is true, and they don't look like critical-path stuff to me. We could almost say that these variables need only be set once per backend startup, but I suppose that would do the wrong thing in a backend that's left running over a daylight-savings transition. What I'm inclined to do is arrange for these variables to be calculated only on-demand, at most once per transaction. It'd be even nicer to get rid of them entirely, but I don't think I understand the time code well enough to venture that. Do you have any comments pro or con on this? regards, tom lane
(back online after a week of downtime) > In utils/adt/nabstime.c, the function GetCurrentAbsoluteTime() is called > during each StartTransaction in order to save the transaction's start > time. It shows up unreasonably high in my profile (> 1% of runtime): > 0.62 10.22 100001/100001 StartTransaction [65] > [91] 1.4 0.62 10.22 100001 GetCurrentAbsoluteTime [91] > 0.92 8.30 100001/100001 localtime [105] > 0.88 0.00 100001/100004 time [305] > 0.12 0.00 100001/104713 strcpy [479] > Now the interesting thing about this is that the essential part of the > function is just the time() call, AFAICS, and that's quite cheap. More > than 90% of the runtime is being spent in the "if (!HasCTZSet)" branch. > I see no reason for that code to be run during every single transaction. > It sets the following variables: > CTimeZone > CDayLight > CTZName > CDayLight is not used *anywhere* except for debug printouts, and could > go away completely. OK, let's kill it. > CTZName is not used if USE_POSIX_TIME is defined, > which is true on most platforms. OK, it should be #ifndef'd > CTimeZone is not quite as useless, but > there are only a couple places where it's used when USE_POSIX_TIME is > true, and they don't look like critical-path stuff to me. > We could almost say that these variables need only be set once per > backend startup, but I suppose that would do the wrong thing in a > backend that's left running over a daylight-savings transition. Right. If we were only supporting WinDoze, then we wouldn't need to worry. But my linux box stays up forever, so daylight savings time transitions are important ;) > What I'm inclined to do is arrange for these variables to be calculated > only on-demand, at most once per transaction. It'd be even nicer to > get rid of them entirely, but I don't think I understand the time code > well enough to venture that. At most once per transaction is what I was hoping the behavior already is. Anyway, if we can take the time() result and *later* figure out the other values, then we could: 1) clear a flag when time() is called 2) use a wrapper around a stripped GetCurrentAbsoluteTime() for date/time support 3) if the flag in (1) is clear, then evaluate the other parameters - Thomas -- Thomas Lockhart lockhart@alumni.caltech.edu South Pasadena, California
Thomas Lockhart <lockhart@alumni.caltech.edu> writes: > (back online after a week of downtime) I was wondering why you were so quiet. Hardware trouble? >> What I'm inclined to do is arrange for these variables to be calculated >> only on-demand, at most once per transaction. > At most once per transaction is what I was hoping the behavior already > is. Actually, my gripe is that it's done in every transaction whether needed or not... > Anyway, if we can take the time() result and *later* figure out > the other values, then we could: > 1) clear a flag when time() is called > 2) use a wrapper around a stripped GetCurrentAbsoluteTime() for > date/time support > 3) if the flag in (1) is clear, then evaluate the other parameters Right, that was pretty much what I was thinking too. As long as CTimeZone &etc are evaluated using the time value saved at the start of the transaction, the behavior will be the same. regards, tom lane
> > (back online after a week of downtime) > I was wondering why you were so quiet. Hardware trouble? In a sense. The server-side modem/ppp setup I use was dead, and I was so busy on other stuff I didn't bug anyone to fix it... > Right, that was pretty much what I was thinking too. As long as > CTimeZone &etc are evaluated using the time value saved at the > start of the transaction, the behavior will be the same. Should I put it on my ToDo? Not sure how to test that it helps with execution time, but I should be able to get to it before 7.0... - Thomas -- Thomas Lockhart lockhart@alumni.caltech.edu South Pasadena, California