On Wednesday 02 of November 2011 11:23:10 michael.vancann...@wisa.be wrote:
> On Wed, 2 Nov 2011, Jonas Maebe wrote:
> > Marco van de Voort wrote on Wed, 02 Nov 2011:
> >> The point was just some encouragement to look further than the immediate
> >> need though, and keep the time call relatively cheap. That doesn't
> >> exclude being correct, it just means a more elaborate implementation.
> > 
> > I do not think that reporting the time correctly taking into account the
> > current time zone and daylight savings time is a function that needs to
> > be treated as performance-critical.
> 
> Under some (not so uncommon) circumstances it is, e.g. for logging
> facilities. Our own eventlog facility would suffer from this.
> 
> >> But harddisk latency can easily be in the half a second to second
> >> magnitude (and then I don't even count spindowns, and am I accessing
> >> directories that I continously access).
> > 
> > If you are stat'ing that file for changes all the time, either the result
> > will be cached or the hard drive won't spin down. And stat'ing a file
> > will not take half a second when done repeatedly.
> 
> I tested this yesterday, using the following sequence:
> 
> fpGettimeOfDay();
> if UseStat then
>    fpStat('/etc/timezone');
> fpGetTimeOfDay();

Please see results about Now() and something that I've mentioned about 
deprecitation of gettimeofday().According to this test, current 
fpgettimeofday() is crap when compared with clock_gettime() (kernel) or libc 
calls (I've copied scenario from kylix sysutils).

*Kernel clock_gettime() NowReal() with 10000000 calls = 4870 ms 
**Libc gettimeofday()+localtime_r() with 10000000 calls = 5085 ms 
***RTL Now() with 10000000 calls = 7659 ms   ?!?!?!? Slowest !?!?


Simple program is attached. Maybe I've added something wrong, but you can 
correct me if I'm wrong.

zeljko


program unixclocks;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, SysUtils,
  unix, baseunix, Libc, SysCall, unixutil;

const
  CLOCK_REALTIME = 0;
  CLOCK_MONOTONIC = 1;
  CLOCK_MONOTONIC_RAW = 4;
  CLOCK_REALTIME_COARSE = 5;
  CLOCK_MONOTONIC_COARSE = 6;
  CLOCKS_MASK = CLOCK_REALTIME or CLOCK_MONOTONIC;

procedure GetDate__(ATime: longint; var Year, Month, Day: word);
var
  hour, minute, second: word;
begin
  EpochToLocal(ATime, year, month, day, hour, minute, second);
end;

procedure GetLocalTimeNew(var SystemTime: TSystemTime; const AClockType: byte);
var
  ASpec: TimeSpec;
begin
  if Do_SysCall(syscall_nr_clock_gettime, AClockType, TSysParam(@ASpec)) = 0 then
  begin
    with SystemTime do
    begin
      EpochToLocal(ASpec.tv_sec, year, month, day, hour, minute, second);
      Millisecond := ASpec.tv_nsec mod 1000;
      GetDate__(ASpec.tv_sec, Year, Month, Day);
    end;
  end;
end;

function NowReal: TDateTime;
var
  SystemTime: TSystemTime;
begin
  GetLocalTimeNew(SystemTime, CLOCK_REALTIME);
  Result := SystemTimeToDateTime(SystemTime);
end;

function NowMono: TDateTime;
var
  SystemTime: TSystemTime;
begin
  GetLocalTimeNew(SystemTime, CLOCK_MONOTONIC);
  Result := SystemTimeToDateTime(SystemTime);
end;

function NowLibc: TDateTime;
var
  T: Libc.time_t;
  TV: Libc.TimeVal;
  UT: Libc.TUnixTime;
begin

  Libc.gettimeofday(TV, nil);
  T := TV.tv_sec;
  Libc.localtime_r(@T, @UT);
  Result := EncodeDate(UT.tm_year + 1900, UT.tm_mon + 1, UT.tm_mday) +
    EncodeTime(UT.tm_hour, UT.tm_min, UT.tm_sec, TV.tv_usec div 1000);
end;

function GetTickCount(const AType: Integer = 0): DWord;
var
  ATime: TDateTime;
begin

  case AType of
    1: ATime := NowReal();
    2: ATime := NowLibc();
    else
      ATime := Now();
  end;
  Result := DWord(Trunc(ATime * 24 * 60 * 60 * 1000))
end;

const
  AMsrInt = 10000000;
var
  i: integer;
  ATicks: DWord;


begin

  ATicks := GetTickCount;
  for i := 0 to AMsrInt - 1 do
    Now();
  writeln(Format('RTL Now() with %d calls = %d ms ', [AMsrInt,
    GetTickCount - ATicks]));

  ATicks := GetTickCount;
  for i := 0 to AMsrInt - 1 do
    NowReal();
  writeln(Format('Kernel clock_gettime() NowReal() with %d calls = %d ms ',
    [AMsrInt, GetTickCount - ATicks]));

  ATicks := GetTickCount;
  for i := 0 to AMsrInt - 1 do
    NowLibc();
  writeln(Format('Libc gettimeofday()+localtime_r() with %d calls = %d ms ',
    [AMsrInt, GetTickCount - ATicks]));

end.

_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to