Performance |
A FlexPendant application cannot meet hard real time demands. There should however be no difference in performance between a FlexPendant SDK application and the standard applications of the device. If your application is slow, the advice in this section will be useful.
![]() |
---|
Do not get overwhelmed by the number of restrictions presented in this section. Most of the time you will not notice any difference if you decide to neglect a few of them. Yet - it is good to know what can be done whenever performance does become an issue. |
A general piece of advice (maybe too obvious a recommendation) is that less code normally means faster code. Remember that methods that are executed frequently, such as OnPaint, event handlers and so on, must be efficient. Everything that can be computed once and stored for future use should be computed only once.
Fewer controller accesses means faster codeThe best thing you can do to improve performance is probably to ensure that you do not access controller functionality more often than necessary. To achieve this you need to understand CAPI, the SDK class libraries used to access robot controller functionality.
It is very easy to use a property of a class and not realize that an access to the controller is actually made. A general recommendation is to try to use subscriptions to controller information (events) where applicable, and let your application store updated values instead of performing numerous reading operations toward the same controller resource.
![]() |
---|
You can easily get an estimate of the number of controller accesses your application performs in different user scenarios by using a robot controller console. The console command robdisp_watch 2 monitors and prints controller accesses made by the FlexPendant to the console. Click a button of your application for example, and study how the FlexPendant and the controller communicate in response to this action. Enter the command robdisp_watch 0 to turn this service off. (The monitor service slows down the response time of your application, due to printing to the console. So do not get worried if your application seems unusually slow!) |
![]() |
---|
Keep in mind that an excessive number of controller accesses will slow down the performance of your application. At worst, it may even affect the performance of the robot controller. |
![]() |
---|
Excessive use of subscriptions may also be a problem. If your application has to handle a continuous load of Rapid data and I/O signal events, and your event handlers need to manipulate the data before presenting it, GUI interaction may become slow. As a rule of thumb, do not estimate more than 20 events/sec. and keep the event handlers thin. |
Fewer objects means better performance. If you know that an object will be used again, create it once and keep a reference. Also, try not to create objects that may not be used.
Reusing existing objects instead of creating new ones is especially important when executing the same code repeatedly, for example in tight loops.
The following example shows how this should be done:
object _o = new object(); for (int i = 0; i < 100000; i++) { ... }
![]() |
---|
Do not create several Controller objects, but reuse it by sending it as a parameter when creating a new view, or share it between classes as a public property. |
Transferring files between the device and the robot controller takes time and also occupies storage memory on the device. Write efficient and fault-tolerant code if it must be done.
Application Framework usage - ITpsViewActivationThe ITpsViewActivation interface is used by TAF to hide and display your application. It has two methods: Activate and Deactivate. The former is called by TAF at the creation of the client view, right after the method has been executed. The latter is called at shut down of the client view, right before the ITpsViewSetup.Uninstall method is executed.
The interface is also used when you select another application on the task bar. TAF then calls ITpsViewActivation.Deactivate (but not ITpsViewSetup.Uninstall ). Likewise, when the application regains focus via the task bar icon, TAF calls ITpsViewActivation.Activate (but not ITpsViewSetup.Install).
It is recommended to enable and disable any subscriptions to controller events in the ITpsViewActivation methods, as valuable resources should not be held when the application is not used. Note that current values should be read before enabling the subscription.
For the same reason, any timers can be activated and deactivated in these methods. That way timers will not run when other applications are in focus, thus saving processor power.
Excessive string manipulation is costlyThe string class is an immutable type, that is, once a string is created its value cannot be changed. This means that string methods that seem to modify the string in fact create new strings.
Look at a this string concatenation example:
string name = "192.168.126.1"; string str = "/" + name + "/" + "RAPID";
Four strings will be appended to one resulting string. No less than four additional strings will be created and allocated when the right hand side of the assignment is executed. A better idea is to use the StringBuilder class or string.Format (which uses the StringBuilder internally):
string str = string.Format("/{0}/RAPID", name);
As a rule, if you are going to do only one string operation on a particular string, you can use the appropriate string method. It is when you start doing numerous string operations that you need to use StringBuilder class or string.Format
Avoid Control.RefreshControl.Refresh() must only be used when an immediate update of the GUI is absolutely required. Refresh makes a direct call to the OnPaint method of the Control, and is therefore much more costly than Control.Invalidate().
Several calls to Invalidate() will not mean several calls to OnPaint. When the GUI thread processes the Invalidate() message all queued up messages of the same control are handled at the same time, thus saving process power.
![]() |
---|
In the 2.0 version of .NET CF there are new methods to be used for GUI controls inheriting System.Windows.Forms.Control:
These methods are used to control GUI updates while modifying a GUI element. The control will not be drawn when SuspendLayout has been called, for example, but is blocked until ResumeLayout is called. |
A common reason for slow code is unintentional boxing and unboxing. To avoid this, you need to be aware of the difference between reference and value types. Reference types (the keyword is used) are always allocated on the heap, while value types are allocated on the stack; unless embedded into a reference type.
Boxing is the operation where a value type, is converted to a reference type. It is done automatically when a reference to a value type is required. Then a new object will be created, allocated on the heap with a copy of the original data.
Here are some examples of not so obvious boxing/unboxing:
Using the foreach statement on an array that contains value types will cause the values to be boxed and unboxed.
Accessing values of a Hashtable with a value type key, will cause the key value to be boxed when the table is accessed.
Using an ArrayList with value types; this should be avoided - use typed arrays instead. Typed arrays are also better because of type safety, as type checking can be performed at compile time.
The following methods should be overridden in order to avoid unnecessary boxing/unboxing: Equals(), GetHashCode().
Using a for loop is often faster than using the foreach statement, especially if a large number of iterations are made. The reason is that the JIT compiler (see About terms and acronyms ) is prohibited to optimize the code execution when foreach is used.
However, foreach makes the code more readable and is therefore a better option when performance is not crucial.
Reflection is performance demandingReflection is a mechanism used to read the meta data of an assembly. The typeof operator, for example, uses reflection to determine the type of an object. Another example is object.ToString(), which also uses reflection.
As reflection is very performance demanding you are recommended to override or to avoid the ToString() method for reference types.
Efficiently parsing XlmXmlTextReader and XmlDocument can both be used to parse xml data. The is the preferred option in most cases; it is more light weight (less memory footprint) and a lot faster to instantiate. The limitation of the XmlTextReader is that forward only reading is possible.
The xml structure may also have an impact on performance. If xml data is organized in non- flat way, search operations will be faster, as a large portion of the information can be skipped. This is achieved by using categories and sub categories.