Best practices for interoperability with Windows Runtime Components (XAML)

Introduction

Interoperability can have a big impact on performance and you might be using it without even realizing that you are. The Windows Runtime handles a lot of the interoperability for you so that you can be more productive and reuse code that was written in other languages. We encourage you to take advantage of what the Windows Runtime does for you, but be aware that it can impact performance. This section discusses things you can do to lessen the impact that interoperability has on your app's performance.

The Windows Runtime has a library of types that are accessible from any language that can write a Windows Store app. You use the Windows Runtime types in C# or Microsoft Visual Basic, the same way you use .NET objects. You don't need to make platform invoke method calls to access the Windows Runtime Components. This makes writing your apps much less complex, but it is important to realize that there might be more interoperability occurring than you expect. If a Windows Runtime Components is written in a language other than C# or Visual Basic, you cross interoperability boundaries when you use that component. Crossing interoperability boundaries can impact the performance of an app.

When you develop a Windows Store app in C# or Visual Basic, the two most common set of APIs that you use are Windows Runtime Components and the .NET APIs for Windows Store apps. In general, types that are defined in the Windows Runtime are in namespaces that begin with "Windows." and .NET types are in namespaces that begin with "System." There are exceptions, though. The types that are listed in .NET APIs for Windows Store apps do not require interoperability when they are used. If you find that you have bad performance in an area that uses Windows Runtime Components, you might be able to use .NET APIs for Windows Store apps instead to get better performance.

Note  

Most of the Windows Runtime Components that ship with Windows 8 are implemented in C++ so you cross interoperability boundaries when you use them from C# or Visual Basic. As always, make sure to measure your app to see if using Windows Runtime Components affects your app's performance before you invest in making changes to your code.

In this topic, when we say "Windows Runtime Components," we mean components that are written in a language other than C# or Visual Basic.

 

Each time you access a property or call a method on a Windows Runtime Components, an interoperability cost is incurred. In fact, creating a Windows Runtime object is more costly than creating a .NET object. The reasons for this are that the Windows Runtime must execute code that transitions from your app's language to the component's language. Also, if you pass data to the component, the data must be converted between managed and unmanaged types.

Using Windows Runtime Components efficiently

If you find that you need to get better performance, you can ensure that your code uses Windows Runtime Components as efficiently as possible. This section discusses some tips for improving performance when you use Windows Runtime Components.

It takes a significant number of calls in a short period of time for the performance impact to be noticeable. A well-designed application that encapsulates calls to Windows Runtime Components from business logic and other managed code should not incur huge interoperability costs. But if your tests indicate that using Windows Runtime Components is affecting your app's performance, the tips discussed in this section help you improve performance.

Consider using .NET APIs for Windows Store apps

There are certain cases where you can accomplish a task by using either Windows Runtime Components or the .NET APIs for Windows Store apps. It is a good idea to try to not mix .NET types and Windows Runtime types. Try to stay in one or the other. For example, you can parse a stream of xml by using either the Windows.Data.Xml.Dom.XmlDocument type (a Windows Runtime type) or the System.Xml.XmlReader type (a .NET type). Use the API that is from the same technology as the stream. For example, if you read xml from a MemoryStream, use the System.Xml.XmlReader type, because both types are .NET types. If you read from a file, use the Windows.Data.Xml.Dom.XmlDocument type because the file APIs and XmlDocument are Windows Runtime components.

Copy Window Runtime objects to .NET types

When a Windows Runtime Components returns a Windows Runtime object, it might be beneficial to copy the returned object into a .NET object. Two places where this is especially important is when you're working with collections and streams.

If you call a Windows Runtime API that returns a collection and then you save and access that collection many times, it might be beneficial to copy the collection into a .NET collection and use the .NET version from then on.

Cache the results of calls to Windows Runtime Components for later use

You might be able to get better performance by saving values into local variables instead of accessing a Windows Runtime type multiple times. This can be especially beneficial if you use a value inside of a loop. Measure your app to see if using local variables improves your app's performance. Using cached values can increase your app's speed because it will spend less time on interoperability.

Combine calls to Windows Runtime Components

Try to complete tasks with the fewest number of calls to Windows Runtime objects as possible. For example, it is usually better to read a large amount of data from a stream than to read small amounts at a time.

Use APIs that bundle work in as few calls as possible instead of APIs that do less work and require more calls. For example, prefer to create an object by calling constructors that initialize multiple properties instead of calling the default constructor and assigning properties one at a time.

Building a Windows Runtime Components

If you write a Windows Runtime Component that can be used by apps written in C++ or JavaScript, make sure that your component is designed for good performance. All the suggestions for getting good performance in apps apply to getting good performance in components. Measure your component to find out which APIs have high traffic patterns and for those areas, consider providing APIs that enable your users to do work with few calls.