从编译代码的纯粹速度角度来看,如果我使用100%XAML或100%代码隐藏或其间的某种组合,它会有所不同吗?代码隐藏中没有像if
语句那样的逻辑 - 它与XAML将加载内容元素的操作完全相同。
如果它确实有所作为,我怎么能测试它在速度方面有多大差异?
答案 0 :(得分:5)
在Silverlight中,XAML在运行时被解析。
因为在XAML中定义的对象的实例化比在代码中定义的对象慢。我编写了一个非常简单的测试,并且在我的测试实例化中,通过编译代码实现对象的速度比解析Xaml快4倍。
Silverlight中的.g.cs文件用于使用x:Name属性声明在XAML中定义的字段。
它也用于调用XAML解析器并在此之后填充字段。请在回复结束时查看.g.cs的示例。
按照我非常简单的测试代码:
的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>
背后的各个MainPage代码:
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();
}
}
}
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>
代码背后:
using System.Windows.Controls;
namespace SilverlightXamlVsCode
{
public partial class SilverlightControl1 : Button
{
public SilverlightControl1()
{
InitializeComponent();
}
}
}
====
请参阅下面的.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")));
}
}
}
答案 1 :(得分:2)
您不太可能在两者之间看到很多性能差异,因为XAML最终会转换为代码并进行编译。通过将所有UI放入纯代码中,您将失去XAML作为以UI为中心的域特定语言提供的优势。重要的是要保持关注点的分离,并将UI布局和样式与驱动UI的代码分开(并且进一步保持这两者与业务逻辑分离),从而生成更易于维护的应用程序。
XAML是一款出色的UI构建工具......比纯代码更适合工作。我建议您以XAML格式保留UI布局和样式。
如果您想了解有关如何构建XAML的更多信息,建议您阅读以下内容:
Building a WPF Application (WPF)
使用WPF,您可以在编译XAML时获得两个生成的文件:表示UI行为的.g.cs文件和.baml文件,它是XAML节点层次结构的紧凑二进制表示形式。使用Silverlight,您可以在.g.cs(或.g.vb)文件中获取生成的代码,但是您没有获得BAML。虽然最终的结果是任何行为都被编译,但是使用Silverlight,您仍然会遇到包含UI节点层次结构的XML文件,而不是更紧凑的二进制表示。 (不确定为什么会这样,Silverlight浏览器控件的限制或可能有限的.NET框架。)
答案 2 :(得分:0)
我试图复制克林格答案的基准调查结果。我发现他的基准测试不能准确测量时间,因为Silverlight直到OnClick函数返回后才进行任何渲染,这意味着在计时器停止计数之前,实际上没有进行任何模板解析或更复杂的XAML工作。我目前没有更好的计时解决方案。
实际标记为正式答案的答案仅适用于WPF。在Silverlight中,XAML不会转换为已编译的代码。