开发者

Silverlight XAML vs. Code-behind

From a pure speed perspective o开发者_如何学Pythonf compiled code, does it make a difference if I use 100% XAML or 100% code-behind or some kind of combination in between? There would be no logic in the code-behind like an if statement - it would do exactly the same as what the XAML would do which is to load content elements.

If it does make a difference, how could I test for how much difference it is making in terms of speed?


In Silverlight XAML is parsed at runtime.

Because of that instantiation of objects defined in XAML are slower than objects defined in code.

I wrote a very simple test and in my test instantiation of objects thru compiled code is around 4 times faster than parsing Xaml.

The .g.cs file in Silverlight is used to declare fields defined in XAML using x:Name attribute.

It's also used to invoke the XAML parser and populate the fields after that.

Please see example of .g.cs at the end of response.

Follow the code for my very simplistic test:

MainPage:

<UserControl x:Class="SilverlightXamlVsCode.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <StackPanel Orientation="Vertical">
        <Button
            Content="Start Xaml"
            Width="150"
            Height="27"
            Click="OnStartXaml" />
        <TextBlock
            x:Name="_startTimeXaml" />
        <TextBlock
            x:Name="_endTimeXaml" />
        <TextBlock
            x:Name="_durationXaml" />

        <ContentControl
            x:Name="_content" />
        <Button
            Content="Start Code"
            Width="150"
            Height="27"
            Click="OnStartCode" />
        <TextBlock
            x:Name="_startTimeCode" />
        <TextBlock
            x:Name="_endTimeCode" />
        <TextBlock
            x:Name="_durationCode" />
    </StackPanel>
</UserControl>

Respective MainPage code behind:

using System;
using System.Windows;
using System.Windows.Controls;

namespace SilverlightXamlVsCode
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void OnStartCode(object sender, RoutedEventArgs e)
        {
            var startTime = DateTime.Now;
            _startTimeCode.Text = startTime.ToString();
            for (int i = 0; i < 10000; i++)
            {
                _content.Content = new Button() {Width = 100, Height = 27, Content = "Code"};
            }
            var endTime = DateTime.Now;
            _endTimeCode.Text = endTime.ToString();

            var duration = endTime - startTime;
            _durationCode.Text = duration.TotalSeconds.ToString();

        }

        private void OnStartXaml(object sender, RoutedEventArgs e)
        {
            var startTime = DateTime.Now;
            _startTimeXaml.Text = startTime.ToString();
            for (int i = 0; i < 10000; i++)
            {
                _content.Content = new SilverlightControl1();
            }
            var endTime = DateTime.Now;
            _endTimeXaml.Text = endTime.ToString();

            var duration = endTime - startTime;
            _durationXaml.Text = duration.TotalSeconds.ToString();            
        }
    }
}

A very minimum control in Xaml:

<Button x:Class="SilverlightXamlVsCode.SilverlightControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="100" Height="27" Content="Xaml">
</Button>

And code behind:

using System.Windows.Controls;

namespace SilverlightXamlVsCode
{
    public partial class SilverlightControl1 : Button
    {
        public SilverlightControl1()
        {
            InitializeComponent();
        }
    }
}

====

See below an example of .g.cs:

#pragma checksum "C:\Workspace\Playplace\SilverlightXamlVsCode\SilverlightXamlVsCode\MainPage.xaml"
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.3603
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Resources;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace SilverlightXamlVsCode 
{
    public partial class MainPage : System.Windows.Controls.UserControl {
        internal System.Windows.Controls.TextBlock _startTimeXaml;
        internal System.Windows.Controls.TextBlock _endTimeXaml;
        internal System.Windows.Controls.TextBlock _durationXaml;
        internal System.Windows.Controls.ContentControl _content;
        internal System.Windows.Controls.TextBlock _startTimeCode;
        internal System.Windows.Controls.TextBlock _endTimeCode;
        internal System.Windows.Controls.TextBlock _durationCode;
        private bool _contentLoaded;

        /// <summary>
        /// InitializeComponent
        /// </summary>
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public void InitializeComponent() {
            if (_contentLoaded) {
                return;
            }
            _contentLoaded = true;

            // INVOKE XAML PARSER HERE
            System.Windows.Application.LoadComponent(this, new System.Uri("/SilverlightXamlVsCode;component/MainPage.xaml", System.UriKind.Relative));

            this._startTimeXaml = ((System.Windows.Controls.TextBlock)(this.FindName("_startTimeXaml")));
            this._endTimeXaml = ((System.Windows.Controls.TextBlock)(this.FindName("_endTimeXaml")));
            this._durationXaml = ((System.Windows.Controls.TextBlock)(this.FindName("_durationXaml")));
            this._content = ((System.Windows.Controls.ContentControl)(this.FindName("_content")));
            this._startTimeCode = ((System.Windows.Controls.TextBlock)(this.FindName("_startTimeCode")));
            this._endTimeCode = ((System.Windows.Controls.TextBlock)(this.FindName("_endTimeCode")));
            this._durationCode = ((System.Windows.Controls.TextBlock)(this.FindName("_durationCode")));
        }
    }
}


You are not likely to see much of a performance difference between the two, as XAML is ultimately translated into code and compiled anyway. By putting all of your UI into pure code, you lose the benefits that XAML has to offer as a UI-centric domain specific language. It is important to maintain a separation of concerns, and keeping your UI layout and styling separated from the the code that drives your UI (and further, keeping both of those separate from your business logic), you produce a more maintainable application.

XAML is an excellent UI construction tool...much better suited for the job than pure code. I recommend keeping your UI layout and styling in XAML form.

If you wish to learn more about how XAML is built, I recommend reading the following:

Building a WPF Application (WPF)

With WPF, you get two generated files as a result of compiling your XAML: a .g.cs file representing the behavior of the UI, and a .baml file which is a compact binary representation of the XAML node hierarchy. With Silverlight, you get the generated code in a .g.cs (or .g.vb) file, but you do not get the BAML. While the ultimate end result is that any behavior IS compiled, with Silverlight you are still stuck with an XML file that contains your UI node hierarchy rather than a more compact binary representation. (Not really sure why this is, limitation of the Silverlight browser control or perhaps the limited .NET framework at its disposal.)


I tried to replicate the benchmark findings of Klinger's answer. I found that his benchmark does not accurately measure the time because Silverlight does not do any rendering until after the OnClick function returns, which means that none of the template parsing or more complex XAML work is actually done until after the timer has stopped counting. I do not have a better timing solution to propose at this time.

The answer that is actually marked as the official answer is only correct for WPF. In Silverlight, XAML is NOT converted to compiled code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜