I need to run an external API call at 200 Hz (every 5ms). Ideally, this fast update call is render-framerate independent, but for simplicity, it would be acceptable if the rate drops for some frames.
Initially, I was looking at creating a thread with a custom update loop, but then I found out that other developers have been using InvokeRepeating with an interval of 5ms to create this kind of fast update loop in a simple manner without any custom threads.
Is InvokeRepeating precise enough to do something every 5ms? What happens if the render-framerate drops?
How could I measure the timings of an InvokeRepeating call to verify that it can hold 5ms steadily? I’ve tried to use a Stopwatch, but I don’t understand the results.
public class MyClass : MonoBehaviour
{
private System.Diagnostics.Stopwatch watch;
private void Start()
{
// Update at 200 hz / every 5 ms
InvokeRepeating("MyFastUpdate", 0f, 0.005f);
watch = System.Diagnostics.Stopwatch.StartNew();
}
private void MyFastUpdate()
{
watch.Stop();
Debug.Log(watch.ElapsedMilliseconds);
watch.Restart();
}
}
This logged very confusing values such as a series of: 0, 0, 15, 0, 7, 32, 0, 0, 16, etc.
I do realize that the overhead of logging or using the stopwatch may exceed a frame time of 5ms, so I tried to remove the log and buffer all timings in a list instead and only log at the end of a short session, but it did not change the results.
Next, I tried a rough approximation:
public class MyClass : MonoBehaviour
{
private int count;
private void Start()
{
// Update at 200 hz / every 5 ms
InvokeRepeating("MyFastUpdate", 0f, 0.005f);
}
private void MyFastUpdate()
{
count++;
}
private void LateUpdate()
{
// How many FastUpdate calls have been processed during this frame?
// At 60 fps this shows roughly 3 calls per LateUpdate.
Debug.Log(count);
count = 0;
}
}
This indeed returned more sensible values such as 3 FastUpdate calls per LateUpdate at roughly 60 fps. However, this is only a very rough measurement.
So, how do I verify that InvokeRepeating does in fact keep my desired update rate without skewing the measurement with additional code? As an aside, the code I’m running within the FastUpdate function is very lightweight and takes less than a millisecond to process on target hardware.