Unit CastleTimeUtils

Description

Time utilities.

Uses

  • BaseUnix
  • Unix
  • Dl
  • SysUtils
  • Math
  • Generics.Collections
  • CastleUtils

Overview

Classes, Interfaces, Objects and Records

Name Description
Record TProcessTimerResult Current time from ProcessTimer.
Record TTimerResult Current time from Timer.
Class TFramesPerSecond Utility to measure frames per second, independent of actual rendering API.
Record TCastleProfilerTime Structure obtained by calling TCastleProfiler.Start.
Class TCastleProfiler Profiler, to measure the speed of execution of your code.

Functions and Procedures

function TimeTickSecondLater(const FirstTime, SecondTime, TimeDelay: TMilisecTime): boolean; deprecated 'to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds';
function TimeTickDiff(const FirstTime, SecondTime: TMilisecTime): TMilisecTime; deprecated 'to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds. Also, this function has non-intuitive argument order, inconsistent with ProcessTimerSeconds and TimerSeconds';
function MilisecTimesAdd(const t1, t2: TMilisecTime): TMilisecTime; deprecated 'to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds';
function MilisecTimesSubtract(const t1, t2: TMilisecTime): TMilisecTime; deprecated 'to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds';
function GetTickCount64: TMilisecTime; deprecated 'to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds';
function DateTimeToAtStr(DateTime: TDateTime): string;
function ProcessTimer: TProcessTimerResult;
function ProcessTimerNow: TProcessTimerResult; deprecated 'use ProcessTimer';
function ProcessTimerDiff(a, b: TProcessTimerResult): TProcessTimerResult; deprecated 'use ProcessTimerSeconds instead';
function ProcessTimerSeconds(const a, b: TProcessTimerResult): TFloatTime;
procedure ProcessTimerBegin; deprecated 'instead of this, better to use a local variable, and ProcessTimer and ProcessTimerSeconds';
function ProcessTimerEnd: TFloatTime; deprecated 'instead of this, better to use a local variable, and ProcessTimer and ProcessTimerSeconds';
function Timer: TTimerResult;
function TimerSeconds(const A, B: TTimerResult): TFloatTime;
function Profiler: TCastleProfiler;

Types

TFloatTime = Double;
TMilisecTime = QWord deprecated 'To measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds' ;

Constants

OldestTime = -MaxDouble;
MinDateTime: TDateTime = MinDouble;
ProcessTimersPerSec = 128 deprecated 'do not use this, it should be only used internally; use ProcessTimerSeconds to compare two times';

Description

Functions and Procedures

function TimeTickSecondLater(const FirstTime, SecondTime, TimeDelay: TMilisecTime): boolean; deprecated 'to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds';

Warning: this symbol is deprecated: to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds

Check is SecondTime larger by at least TimeDelay than FirstTime.

Simple implementation of this would be SecondTime - FirstTime >= TimeDelay.

FirstTime and SecondTime are milisecond times from some initial point. For example, they may be taken from a function like 32-bit GetTickCount (on older Windows; on newer we use GetTickCount64). Such time may "wrap". This function checks these times intelligently, using the assumption that the SecondTime is always "later" than the FirstTime, and only having to check if it's later by at least TimeDelay.

Always TimeTickSecond(X, X, 0) = True. that is, when both times are actually equal, it's correctly "later by zero miliseconds".

function TimeTickDiff(const FirstTime, SecondTime: TMilisecTime): TMilisecTime; deprecated 'to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds. Also, this function has non-intuitive argument order, inconsistent with ProcessTimerSeconds and TimerSeconds';

Warning: this symbol is deprecated: to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds. Also, this function has non-intuitive argument order, inconsistent with ProcessTimerSeconds and TimerSeconds

Difference in times between SecondTime and FirstTime.

Naive implementation would be just SecondTime - FirstTime, this function does a little better: takes into account that times may "wrap" (see TimeTickSecondLater), and uses the assumption that the SecondTime for sure "later", to calculate hopefully correct difference.

function MilisecTimesAdd(const t1, t2: TMilisecTime): TMilisecTime; deprecated 'to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds';

Warning: this symbol is deprecated: to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds

Simply add and subtract two TMilisecTime values.

These don't care if TMilisecTime is a point in time, or time interval. They simply add / subtract values. It's your problem if adding / subtracting them is sensible.

Range checking is ignored. In particular, this means that if you subtract smaller value from larger value, the result will be like the time "wrapped" in between (since TMilisecTime range is limited).

function MilisecTimesSubtract(const t1, t2: TMilisecTime): TMilisecTime; deprecated 'to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds';

Warning: this symbol is deprecated: to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds

 
function GetTickCount64: TMilisecTime; deprecated 'to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds';

Warning: this symbol is deprecated: to measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds

Get current time, in miliseconds. On newer OSes (non-Windows, or Windows >= Windows Vista) this uses 64-bit int under the hood. Or older Windows versions it's based on 32-bit Windows.GetTickCount that measures time since system start, that will wrap in ˜ 49 days.

function DateTimeToAtStr(DateTime: TDateTime): string;

Convert DateTime to string in the form "date at time".

function ProcessTimer: TProcessTimerResult;

Current time, local to this process. Use this to measure and compare the time it takes your program to do some calculations.

If possible, this measures only the CPU usage of this process. So it ignores delays caused by other processes doing something on your system, and it ignores things like waiting for hard disk (I/O). This is possible on Unix thanks to the clock API, see http://www.gnu.org/software/libc/manual/html_node/Processor-And-CPU-Time.html . On other platforms (like Windows), this simply measures real time that passed.

You usually take two ProcessTimer values, subtract them with ProcessTimerSeconds, and this is the time that passed – in seconds. Like this:

var
  TimeStart: TProcessTimerResult;
  Seconds: TFloatTime;
begin
  TimeStart := ProcessTimer;
  // ...  do something time-consuming ...
  Seconds := ProcessTimerSeconds(ProcessTimer, TimeStart);
  // or: Seconds := TimeStart.ElapsedTime;
  WritelnLog('Seconds passed (in this process): %f', [Seconds]);
end;

function ProcessTimerNow: TProcessTimerResult; deprecated 'use ProcessTimer';

Warning: this symbol is deprecated: use ProcessTimer

 
function ProcessTimerDiff(a, b: TProcessTimerResult): TProcessTimerResult; deprecated 'use ProcessTimerSeconds instead';

Warning: this symbol is deprecated: use ProcessTimerSeconds instead

Subtract two times obtained from ProcessTimer, A-B, return a difference in ProcessTimersPerSec.

Although it may just subtract two values, it may also do something more. For example, if timer resolution is only miliseconds, and it may wrap (just like TMilisecTime), then we may subtract values intelligently, taking into account that time could wrap (see TimeTickDiff).

function ProcessTimerSeconds(const a, b: TProcessTimerResult): TFloatTime;

Subtract two times obtained from ProcessTimer, A-B, return a difference in seconds.

procedure ProcessTimerBegin; deprecated 'instead of this, better to use a local variable, and ProcessTimer and ProcessTimerSeconds';

Warning: this symbol is deprecated: instead of this, better to use a local variable, and ProcessTimer and ProcessTimerSeconds

Simple measure of process CPU time. Call ProcessTimerBegin at the beginning of your calculation, call ProcessTimerEnd at the end. ProcessTimerEnd returns a float number, with 1.0 being one second.

Note that using this is unsafe in libraries, not to mention multi-threaded programs (it's not "reentrant") — you risk that some other code called ProcessTimerBegin, and your ProcessTimerEnd doesn't measure what you think. So in general units, do not use this, use ProcessTimer and ProcessTimerSeconds instead.

function ProcessTimerEnd: TFloatTime; deprecated 'instead of this, better to use a local variable, and ProcessTimer and ProcessTimerSeconds';

Warning: this symbol is deprecated: instead of this, better to use a local variable, and ProcessTimer and ProcessTimerSeconds

 
function Timer: TTimerResult;

Timer to measure (real) time passed during some operations. It is a "real" time, which means that subtracting two values measures the actual time that passed between two events. Contrast this with ProcessTimer that tries to measure only CPU time used by the current process.

Call Timer twice, and calculate the difference (in seconds) using the TimerSeconds. Like this:

var
  TimeStart: TTimerResult;
  Seconds: TFloatTime;
begin
  TimeStart := Timer;
  // ...  do something time-consuming ...
  Seconds := TimerSeconds(Timer, TimeStart);
  // or: Seconds := TimeStart.ElapsedTime;
  WritelnLog('Seconds passed: %f', [Seconds]);
end;

function TimerSeconds(const A, B: TTimerResult): TFloatTime;

Subtract two times obtained from Timer, A-B, return a difference in seconds.

function Profiler: TCastleProfiler;

Single instance of TCastleProfiler that you can use for all profiling. Castle Game Engine uses it to report loading times of various assets automatically.

Types

TFloatTime = Double;

Time in seconds. This is used throughout my engine to represent time as a floating-point value with good accuracy in seconds.

Using the "double" precision (not just "single") is good to guarantee good accuracy. It is also the precision required for storing time in X3D. See also: https://randomascii.wordpress.com/2012/02/13/dont-store-that-in-a-float/ https://twitter.com/ID_AA_Carmack/status/418158611664097280

To test that "single" is not enough, open some animation in view3dscene, and change "on display" time pass to 1000. It goes even better if AutoRedisplay is False, and LimitFps is 0.0, and model is still for some time — then we do many OnUpdate calls with very small SecondsPassed values.

TMilisecTime = QWord deprecated 'To measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds' ;

Warning: this symbol is deprecated: To measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds

To measure time, better use Timer + TimerSeconds or ProcessTimer + ProcessTimerSeconds

Constants

OldestTime = -MaxDouble;
 
MinDateTime: TDateTime = MinDouble;
 
ProcessTimersPerSec = 128 deprecated 'do not use this, it should be only used internally; use ProcessTimerSeconds to compare two times';

Warning: this symbol is deprecated: do not use this, it should be only used internally; use ProcessTimerSeconds to compare two times

Resolution of the timer used by ProcessTimer.


Generated by PasDoc 0.15.0.