Обсуждение: [PATCH] replace float8 with int in date2isoweek() and date2isoyear()

Поиск
Список
Период
Сортировка

[PATCH] replace float8 with int in date2isoweek() and date2isoyear()

От
Фуканчик Сергей
Дата:
Hi PG hackers,

I found suspicious use of float8 in date2isoweek() and date2isoyear(). In both
cases float8 is only used for storing the value, while the entire calculation
on the right happens in integers:

 float8 result = (dayn - (day4 - day0)) / 7 + 1;

At the end date2isoweek() returns `result' converted back to int:

 return (int) result;

float8 here is confusing and a bit slow.

I run a benchmark with optimization -O3, and found that using int is 3% faster:

BM_Float/1000/3/8_mean         5.12 ns         5.12 ns          100
BM_Int/1000/3/8_mean            4.95 ns         4.95 ns          100
BM_Long/1000/3/8_mean         4.96 ns         4.96 ns          100

Without optimization (-O0), speedup even better around 30%:

BM_Float/1000/3/8_mean         19.6 ns         19.6 ns          100
BM_Int/1000/3/8_mean             14.8 ns         14.8 ns          100
BM_Long/1000/3/8_mean          16.7 ns         16.7 ns          100

Additionally, as a paranoia measure I run a comparison test with the following
ranges: year={-100000,100000}, month={-100,+100}, day={-100,+100}.
As expected float and int did not produce any difference.

Attached patch replaces `float8 result' with `int result'.

I think there is no need in adding an extra test case here, because
date2isoweek and date2isoyear are covered by three regression tests:
* date
 SELECT f1 as "date",
     ...
     date_part('isoyear', f1) AS isoyear,
     date_part('week', f1) AS week,
     date_part('dow', f1) AS dow,
     date_part('isodow', f1) AS isodow,
 ...
     FROM date_tbl;
* timestamp
 SELECT date_trunc( 'week', timestamp '2004-02-29 15:44:17.71393' ) AS week_trunc;
* timestamptz
 SELECT date_trunc( 'week', timestamp with time zone '2004-02-29 15:44:17.71393' ) AS week_trunc;
---
Sergey

Вложения

Re: [PATCH] replace float8 with int in date2isoweek() and date2isoyear()

От
Tom Lane
Дата:
=?utf-8?q?=D0=A4=D1=83=D0=BA=D0=B0=D0=BD=D1=87=D0=B8=D0=BA_=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9?=
<s.fukanchik@postgrespro.ru>writes: 
> Hi PG hackers,
> I found suspicious use of float8 in date2isoweek() and date2isoyear(). In both
> cases float8 is only used for storing the value, while the entire calculation
> on the right happens in integers:

>  float8 result = (dayn - (day4 - day0)) / 7 + 1;

> At the end date2isoweek() returns `result' converted back to int:

>  return (int) result;

> float8 here is confusing and a bit slow.

I looked into our git history to try to find out why it's like this.
The answer seems to be that commit dffd8cac3 created date2isoweek()
by splitting out pre-existing code that had been in timestamp_part().
In that context the code had been using a float8 "result" variable
that was shared with other switch cases, and that variable's type
was just blindly copied into date2isoweek().  Then 1c757c49f again
copied-and-pasted while creating date2isoyear().

I agree with getting rid of the unnecessary usage of float8 here,
but there's another aspect that's bugging me: "result" is a totally
misleading variable name in date2isoyear(), because it's *not*
the function's result.  I'm inclined to rename it to "week", and
then to keep these functions looking as parallel as possible,
I'd probably do the same in date2isoweek().

> I think there is no need in adding an extra test case here, because
> date2isoweek and date2isoyear are covered by three regression tests:

Agreed, the code coverage report shows these are covered.

            regards, tom lane



Re: [PATCH] replace float8 with int in date2isoweek() and date2isoyear()

От
Sergey Fukanchik
Дата:
Sure,

I'm attaching v2 of the patch with "result" renamed to "week".

--

Sergey

On 7/12/25 18:15, Tom Lane wrote:
> =?utf-8?q?=D0=A4=D1=83=D0=BA=D0=B0=D0=BD=D1=87=D0=B8=D0=BA_=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9?=
<s.fukanchik@postgrespro.ru>writes:
 
>> Hi PG hackers,
>> I found suspicious use of float8 in date2isoweek() and date2isoyear(). In both
>> cases float8 is only used for storing the value, while the entire calculation
>> on the right happens in integers:
>>   float8 result = (dayn - (day4 - day0)) / 7 + 1;
>> At the end date2isoweek() returns `result' converted back to int:
>>   return (int) result;
>> float8 here is confusing and a bit slow.
> I looked into our git history to try to find out why it's like this.
> The answer seems to be that commit dffd8cac3 created date2isoweek()
> by splitting out pre-existing code that had been in timestamp_part().
> In that context the code had been using a float8 "result" variable
> that was shared with other switch cases, and that variable's type
> was just blindly copied into date2isoweek().  Then 1c757c49f again
> copied-and-pasted while creating date2isoyear().
>
> I agree with getting rid of the unnecessary usage of float8 here,
> but there's another aspect that's bugging me: "result" is a totally
> misleading variable name in date2isoyear(), because it's *not*
> the function's result.  I'm inclined to rename it to "week", and
> then to keep these functions looking as parallel as possible,
> I'd probably do the same in date2isoweek().
>
>> I think there is no need in adding an extra test case here, because
>> date2isoweek and date2isoyear are covered by three regression tests:
> Agreed, the code coverage report shows these are covered.
>
>             regards, tom lane
Вложения

Re: [PATCH] replace float8 with int in date2isoweek() and date2isoyear()

От
Tom Lane
Дата:
Sergey Fukanchik <s.fukanchik@postgrespro.ru> writes:
> I'm attaching v2 of the patch with "result" renamed to "week".

I pushed it already, actually.

            regards, tom lane



Re: [PATCH] replace float8 with int in date2isoweek() and date2isoyear()

От
Sergey Fukanchik
Дата:
Thank you!

--

Sergey

On 7/13/25 18:39, Tom Lane wrote:
> Sergey Fukanchik <s.fukanchik@postgrespro.ru> writes:
>> I'm attaching v2 of the patch with "result" renamed to "week".
> I pushed it already, actually.
>
>             regards, tom lane