This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: advise on future of glibc (mktime issue)


Jakub Jelinek wrote:

On Tue, Jun 07, 2005 at 10:35:48AM -0400, Jairo19@interhosting.us wrote:


I contacted RH and they say they will not change the behavior of their glibc because they prefer "correctness over performance" and they believe glibc should be checking for changes to the timezone. Their suggestions are: build our own glibc and loose RH support, rewrite mktime for our own use (I tried that but seemed a little complicated and looses the benefit of the library per se), and lastly they suggested to set TZ=/etc/localtime (which makes the program run a little faster, but not as fast as RH7.3).



I certainly can't reproduce contemporary glibc being any slower than RH7.3 glibc with TZ=/etc/localtime:

$ LC_ALL=C time ~/7.3-glibc/ld-linux.so.2 --library-path ~/7.3-glibc/ /tmp/mktimetest
1.74user 0.00system 0:01.74elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+93minor)pagefaults 0swaps
$ LC_ALL=C TZ=/etc/localtime time ~/7.3-glibc/ld-linux.so.2 --library-path ~/7.3-glibc/ /tmp/mktimetest
1.66user 0.00system 0:01.66elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+93minor)pagefaults 0swaps
$ LC_ALL=C time /lib/ld-linux.so.2 --library-path /lib /tmp/mktimetest
1.94user 13.73system 0:15.68elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+100minor)pagefaults 0swaps
$ TZ=/etc/localtime time /lib/ld-linux.so.2 --library-path /lib /tmp/mktimetest
1.36user 0.00system 0:01.36elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+100minor)pagefaults 0swaps

~/7.3-glibc/ has glibc-2.2.5-34.i686.rpm's /lib dir unpacked, /lib
contains 2.3.5 glibc.  All is on a FC3 box, but with TZ=/etc/localtime the
loop does not do any syscalls, so the kernel shouldn't matter much.
Here, glibc 2.3.5 is actually faster than 2.2.5 if TZ=/etc/localtime is
used.



It is widely known that FC1,2,3 and RHEL* are slow systems, and I always figured it was for the better, then I question, how may of this


Do you have any data to back up your claims?




little changes in glibc exists in RH's patches that by themselves may not be a big performance hit, but put them together and you get a slower system ?



You can easily check yourself, each Red Hat glibc src.rpm includes a tarball with the upstream CVS checkout and a patch. I'm not aware of any changes from upstream glibc that could noticeably affect performance.



I need to know the weekday for millions of dates, I guess I could use
a hash (I would need to find a library for that) for it, but everything
was fine until I started using RHEL4 with the patched glibc. Any
suggestions ?



I might be missing something obvious, but if all you need is the weekday for dates stored in the year*10000+month*100+day format and you need to do it that many times, then surely writing your own function will be uncomparably faster than doing expensive mktime and localtime.

I haven't put any effort into optimizing this and you can get away
even without mktime calls or just one, not just caching tm_wday
of Jan, 1st for each year.  Still, it is more than 60 times faster:

LC_ALL=C time /lib/ld-linux.so.2 --library-path /lib /tmp/mktimetest2
0.02user 0.00system 0:00.02elapsed 96%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+101minor)pagefaults 0swaps

int real_get_dayofweek(int date)
{
// extract day/yr/mn
int day = date % 100;
int month = (date % 10000) / 100;
int year = date / 10000;

struct tm time;
time.tm_sec = 0;  time.tm_min = 30;  time.tm_hour = 9;  time.tm_mday = day;  time.tm_mon = month - 1;
time.tm_year = year - 1900;

time_t time1 = mktime(&time);

return(localtime(&(time1))->tm_wday); // Sun=0, Sat=6

} //get_dayofweek

static unsigned char year_to_wday[200];

int get_dayofweek(int date)
{
 // extract day/yr/mn
 int day = date % 100;
 int month = (date % 10000) / 100;
 int year = date / 10000;
 int leapyear = (year & 3) == 0 && ((year % 100) != 0 || (year % 400) == 0);
 static const unsigned short int mon_yday[2][13] =
 {
   /* Normal years.  */
   { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
   /* Leap years.  */
   { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
 };
 if (year < 1900 || year >= 2100)
   return real_get_dayofweek (date);
 return (year_to_wday[year - 1900] + mon_yday[leapyear][month] + day - 1) % 7;
}

void init_year_to_wday (void)
{
 int date;
 for (date = 0; date < 200; date++)
   year_to_wday[date] = real_get_dayofweek(date * 10000 + 19000101);
}

Jakub




Hola:


Jakub thanks for your answer.

    I ran tests in my DUAL Athlon with RH7.3 installed (compiled in 7.3):
linux3 >time ~/temp/test_mktime_7.3

real    0m2.263s
user    0m2.260s
sys     0m0.000s

linux3 >rpm -q glibc
glibc-2.2.5-44

linux3 >LC_ALL=C time ~/temp/test_mktime_7.3
Command exited with non-zero status 1
2.27user 0.00system 0:02.27elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (139major+13minor)pagefaults 0swaps


Now in the same machine with FC3 (compiled in FC3): linux2 >time ./test_mktime rpm -q real 0m7.023s user 0m3.157s sys 0m3.864s

linux2 >rpm -q glibc
glibc-2.3.5-0.fc3.1

linux2 >LC_ALL=C time ./test_mktime
Command exited with non-zero status 1
3.21user 3.74system 0:06.96elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+232minor)pagefaults 0swaps


Check the difference in the time used by the System, but also the difference in the time used by the program.


Now I set the timezone to TZ=/etc/localtime
linux2 >export TZ=/etc/localtime

linux2 >time ./test_mktime

real    0m2.628s
user    0m2.618s
sys     0m0.005s

linux2 >time ./test_mktime

real    0m2.652s
user    0m2.644s
sys     0m0.004s

linux2 >LC_ALL=C time ./test_mktime
Command exited with non-zero status 1
2.63user 0.00system 0:02.63elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+232minor)pagefaults 0swaps


which shows that FC3 is still slower than RH7.3


I can' t explain the difference, I was hoping you could.

Regarding my claim, searching google for +Performance +Fedora will get you a lot of claims, I don't have a way to quantify it of course, but I can tell you that my Realworld programs run slower in the same machine running the FC3 and RHEL4, than running RH7.3 even after removing the calls to mktime.

As I said, it may not be one change that affects performance noticeable, but many small performance impacts can amount to the whole problem. I also agree that if they are needed changes and everybody adopts them, then we have to move on.

I'm just trying to make an educated decision on what to do next given the fact that my programs run slower in FC3 and RHEL4. I cannot accept a my runs to go from 1 day to 3 days.

I will try your suggestion, it seems it may be the workaround I need.

Thanks,



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]