Timer.Translate – Performance optimization
The Experior Translate has some serious performance issues, but it is difficult to do something about it without affecting existing solutions using it.
Here is what we decided to do:
The existing property ‘Animate’ has been renamed to ‘AutoUpdatePositions’ (Animate still exist but marked obsolete).
Reason for the name change is that not only animation is affected but also positions of Assemblies/Parts added to the translate timer, will not be updated until translation is done.
// Create a translate timer as per usual:
Core.Timer.Translate _translateTimer = new Core.Timer.Translate();
// Configure _translateTimer
private void ConfigureTranslateTimer()
_translateTimer.AutoUpdatePositions = false;
A new method ‘UpdatePositions’ has been added. This allows users to manually update positions of Assemblies/Parts added to the translate timer when AutoUpdatePosition is false.
This solves the problem we used to have with slow simulations when the translate timer is used and with a few extra steps (for the user), there are almost no loss of precision or functionality.
If ‘AutoUpdatePositions’ is set to false, simulations using translate timers will run a lot faster. This has 3 side effects:
1.The translation is no longer animated.
However, if users implement a real time timer that calls UpdatePositions every 1/30 sec. then animation is back to normal, and the simulation still runs a lot faster.
// Setup a real time timer somewhere (e.g. in a Controller):
System.Timers.Timer updateTimer = new System.Timers.Timer(1/30.0);
updateTimer.AutoReset = true;
updateTimer.Elapsed += UpdateTimer_Elapsed;
// Call UpdatePosition on Elapesed
private void UpdateTimer_Elapsed(object sender, ElapsedEventArgs e)
2. Positions are not updated until translation is done.
However, if users call UpdatePositions just before asking for a position of any Assembly/Part added to the timer, the return value should be as precise as if AutoUpdatePositions were true.
// Lets say we need a position of an assembly while it is being translated by _translateTimer
var position = MyAssembly.Position;
3. OnPositionChanged events are not raised on every timestep when AutoUpdatePositions is false, only when
UpdatePositions is called by the user. This may have an impact in some project.
How it used to work in Experior 6 and why there is a difference in Experior 7:
In Experior 7 there has been focus on making simulations deterministic. That means a simulation should yield the same results when it is run multiple times and in different environments e.g. on another computer.
To accomplish this we needed to separate the UI thread from the engine thread where simulation related calculations are done.
In Experior 6, the UI update rate (which was user adjustable) was directly responsible for initiating the update of assemblies. That means, if the framerate was set to 5, then positions of Assemblies/Parts added to a translate timer would be updated 5 times per real-time second, no matter the simulation time scale. This could in some cases yield different results whether the framerate was set to 5 or 60 and whether timescale was 1 or infinity. That also means if the framerate was set to 0, much fewer calculations were needed and hence the simulations were running very fast, although non deterministic.
In Experior 7, the engine thread is responsible for initiating update of assemblies. When the simulation target time scale is at infinity, the time steps are as large as it takes the computer to do all necessary calculations. If the time scale is 1 (real time), the engine step method inserts pauses in every step to accomplish the target time scale of 1 real-time second. That means the same amount of calculations is needed no matter time scale or framerate and hence the simulations are running slower.