How to giva a time accurate timer in Fire Monkey? - delphi

I have to display a timer in 10th second for a sport competition. I have do this using the OnTimer event of a TTimer. the interval is set to 100. My routine display the current min:sec.10th (ex.: 02:45.7 ) correctly but it seem that my timer loose about 4 second at each minutes if I comp. to normal clock.
There is a better way to get a time accuracy timer in Delphi XE2 (or XE3) ?

You can use a timer to display the current value of the clock, but use a different approach to calculate the elapsed time.
You have to know that Windows timers are not time accurate, and even if you set it to elapse every 100 milliseconds, it can take more to fire the OnTimer event and even it can miss some intervals if for some reason elapses two or more times before your application process it.
You can, for example, use the system high-resolution performance counter to track times with nano-second accuracy.
You can also use the Delphi TStopwatch class, which encapsulates the system calls and falls back to other method (GetTickCount) if the high resolution performance counter is not available in your machine.
Take also a look at the How to Accurately Measure Elapsed Time Using High-Resolution Performance Counter delphi.about.com article.

Related

How much computing time does the kernel need

I wrote a program for a LED display. The program allows to set the refresh rate via webconfiguration. To meet the refresh rate I measure the processing time of a loop. At the end I calculate the delay and wait until the next loop.
e.g. Refresh Rate 5 Hz -> 200 milli seconds for one loop. 50 milli seconds computing time results in 150 milli seconds delay.
The ratio of process time (50 milli seconds) to total time (200 milli seconds) indicates the processor load of my program. But to find the optimal setting, I need the actual total processor load. And not only that of my program. But since I don't know the real processor load of the delay() (in which WIFI etc. is done), I don't really know the processor load. In other words, I don't know how much time the system spends doing system tasks in the delay(150).
Is there a way to find out how much of a delay is actually used for system tasks before the processor truly waits?
In other words, I'm looking for a way to get the kernel time within a certain time frame.
Cheers Gabriel

(When) Does CACurrentMediaTime/mach_system_time wrap around on iOS?

To get accurate time measurements on iOS, mach_absolute_time() should be used. Or CACurrentMediaTime(), which is based on mach_absolute_time(). This is documented in this Apple Q&A, and also explained in several StackOverflow answers (e.g. https://stackoverflow.com/a/17986909, https://stackoverflow.com/a/30363702).
When does the value returned by mach_absolute_time() wrap around? When does the value returned by CACurrentMediaTime() wrap around? Does this happen in any realistic timespan? The return value of mach_absolute_time() is of type uint64, but I'm unsure about how this maps to a real timespan.
The document you reference notes that mach_absolute_time is CPU dependent, so we can't say how much time must elapse before it wraps. On the simulator, mach_absolute_time is nanoseconds, so if it's wrapping at UInt64.max, that translates to 585 years. On my iPhone 7+, it's 24,000,000 mac_absolute_time per second, which translates to 24 thousand years. Bottom line, the theoretical maximum amount of time captured by mach_absolute_time will vary based upon CPU, but you won't ever encounter this in any practical application.
For what it's worth, consistent with those various posts you found, the CFAbsoluteTimeGetCurrent documentation warns that:
Repeated calls to this function do not guarantee monotonically increasing results. The system time may decrease due to synchronization with external time references or due to an explicit user change of the clock.
So, you definitely don't want to use NSDate/Date or CFAbsoluteTimeGetCurrent if you want accurate elapsed times. Neither ensures monotonically increasing values.
In short, when I need that sort of behavior, I generally use CACurrentMediaTime, because it enjoy the benefits of mach_absolute_time, but it converts it to seconds for me, which makes it very simple to use. And neither it nor mach_absolute_time are going to loop in any realistic time period.

objective-c - NSTimer falling more and more behind

I have a NSTimer (running on main thread) that is supposed to go off every 0.02s. However, I notice that as memory usage start going up (the app captures a frame every tick and stores in an array) subsequent ticks begin to take more then 0.02s.
How can I solve this issue? I'm starting to think NSTimer is not suited for high-frequency tasks like this.
As the docs state,
A timer is not a real-time mechanism; it fires only when one of the
run loop modes to which the timer has been added is running and able
to check if the timer’s firing time has passed. Because of the various
input sources a typical run loop manages, the effective resolution of
the time interval for a timer is limited to on the order of 50-100
milliseconds.
Since 100 milliseconds = .1 seconds and your timer is supposed to run every 0.02 seconds, your timer schedule is far shorter than the timer's effective resolution and so you timer can easily get out of sync.

calculate time to arrive in a procedure

I want to determine necessary time to execute a procedure, time value must be returned in the first instruction in this procedure, like this:
procedure myProcedure;
begin
// determine necessary time here
//other instructions
end;
First, of all, is this possible? if yes, how can I do this?
Thanks for your replies
In general you cannot expect to do this. Unless you have carefully profiled the code on the machine on which you run it, under the exact conditions in which it runs. Without that information there's no way to reliably predict run time up front.
You actually want to display progress. Typically you do that by keeping track of how the overall task is progressing. If the task is made up of 50 similarly sized sub tasks, then you can measure proportion complete simply by knowing how many sub tasks are complete.
That's the normal way to measure progress for a progress bar. If you wish to estimate time to completion then make a note of when the task starts. Then, as worl proceeds, you can use simple maths to work out an estimate of the time remaining. If the first 10 sub tasks took 30 seconds, then estimate that the next 10 will take another 30 seconds.

Execute action every x seconds delphi

I'm trying to execute a function(or procedure) every x seconds.
I've been looking everywhere but never seemed to find something that suits my needs.
My application basically gets data from the web and I want to make an auto-refresh checkbox.
So let's say the user checks the box, I want the app to call that function every 5 seconds.
Thanks!
Use a TTimer (from the System tab in the component palette). Set the interval to the number of seconds * 1000 (converting from milliseconds to seconds), and write a handler for the OnTimer event.
The simplest way it to use the TTimer component, part of Delphi's standard VCL. Put one on the form, make sure Enabled is set to True, set Interval to 5000 (the value is in milliseconds), and assign its OnTimer event, where you'll put the code that needs to run every 5 seconds.
Sometimes it is a good idea to start with the timer disabled, then set its Enabled property to true in code, so that the timer starts to fire after everything else in your application has been properly set up.
The timer may not be firing in exact 5-second intervals, since timer messages have low priority in Windows and may not be received if the CPU is doing a lot of other work. Since your interval is relatively long, you might set the timer to fire every second (Interval := 1000) or even a few times per second, and check current time every time it fires. Perform the update if current time is later by 5 seconds or more from the time of the last update. (Use the SecondsBetween function in DateUtils unit to make that determination).
I don't have Delphi at the moment, but I'm pretty sure there was a TTimer component in the control palette, and according to this, I think I'm right.

Resources