7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Xamarin.Forms 1.5.1-pre1] XamlC (XAMLプリコンパイル)

Last updated at Posted at 2015-10-05

XamlCの概要

Xamarin.Forms 1.5.1-pre1がアナウンスされ、その中に XamlC と呼ばれる機能が含まれています。

Xamarin.Forms 1.5.1-pre1 Released - Xamarin Forums

以下の効果があります。

  • 実行時にXAMLを解析しないことによるロード時間の減少
  • アセンブリに.xmlファイルを含まなくなることによるアプリサイズの減少

XamlCの有効化は属性で指定します。

アセンブリ全体で有効化:
[assembly:Xamarin.Forms.Xaml.XamlCompilation (Xamarin.Forms.Xaml.XamlCompilationOptions.Compile)]

クラス単位で有効化:
[Xamarin.Forms.Xaml.XamlCompilation (Xamarin.Forms.Xaml.XamlCompilationOptions.Compile)]

注意
XamlCはβテスト版です、XF 1.5.1正式版までに外される可能性があります。(以前もPreview版に盛り込まれましたが「今はバグフィックスを優先する」と先送りにされました。)

Xamarin.FormsにおけるXAML解釈

PageやViewの新規作成時にXAML付きのテンプレートを選ぶと、.xamlファイルとpartial指定付きの.csファイルが生成されます。そして、
実行時に.csファイルのコンストラクタ内の InitializeComponent() で.xamlファイルをパースしViewを組み上げていくという仕組みです。

XamlCはコンパイル時にXAMLを解析し、相当するILを生成します。

XamlCompilationOptions

ちなみに XamlCompilationOptions の定義はこうなっています。

[Flags]
public enum XamlCompilationOptions
{
	Skip = 1,
	Compile = 2
}

XamlCompilationOptions.Skip はアセンブリ全体でXamlCを有効にしたうえで、特定のクラスだけプリコンパイルさせたくない時に使います。(多分)

試してみる

(※環境はMac&Xamarin Studioです)

ソリューション作成から「Blank Xamarin.Forms App」で新規作成します。(今回はSharedにしました)

iOS、AndroidのプロジェクトのXamarin.Formsを1.5.1-pre1に更新します。(Preview版nugetパッケージへの更新方法は以前の記事にスクリーンショット付きの手順があります。)

Sharedプロジェクトに新しいContentPage(XAML)を追加します。

App クラスを修正します。

MainPage = new MyPage();

本当にプリコンパイルされているか?

Labelのスペルをわざと間違えて"Lable"にしてみます。

	<ContentPage.Content>
		<Lable Text="Hello XamlC!"/>
	</ContentPage.Content>

.csファイルにはXamlCompilation属性を指定します。

	[Xamarin.Forms.Xaml.XamlCompilation (Xamarin.Forms.Xaml.XamlCompilationOptions.Compile)]
	public partial class MyPage : ContentPage

ビルドすると...

スクリーンショット 2015-10-05 19.41.38.jpg

おお!コンパイル時点でエラーになりました。ちゃんとXamlCが働いているようです。

おまけ:存在しないプロパティ

Labelの部分を少し修正してみました。

<Label Text="Hello XamlC!" ForeColor="#FF8888" />

正しいプロパティ名はTextColorで"ForeColor"というプロパティはLabelクラスには存在しません。

結果

エラー無くコンパイルされ、実行時例外も発生しませんでした。これはAttached Property(例 Grid.Row)のようにコントロールに存在しないプロパティが書かれる場合があるため、エラーにできていないように思えます。

...でもXamlCオフだと実行時例外なんですよね、コレ。

おまけ:間違ったプロパティ値の指定

今度は値の方を間違えてみました。TextColorをWebカラー式に指定しようとして、先頭の「#」が抜けています。

<Label Text="Hello XamlC!" TextColor="FF8888" />

結果

実行時例外となりました。これは IValueConverter.Convert() を呼び出すILに変換されたため、実行時にstringからColorへ変換できずに例外発生になったものと思われます。
プリコンパイル時にダイレクトに代入するコードに変換してくれるようになるといいですね。(オーバーヘッドも減るし、間違いにも気付けるので)

速度的な話

肝心の高速化の検証。

.xaml側はこう、

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="XamlC.MyPage">
	<ContentPage.Content>
		<Label />
	</ContentPage.Content>
</ContentPage>

.csは InitializeComponent() にかかった時間を計測します。

public MyPage()
{
	var stopwatch = Stopwatch.StartNew();
	InitializeComponent();
	stopwatch.Stop();
	((Label)Content).Text = stopwatch.ElapsedMilliseconds + "ms";
}

ほいで計測手順と環境

  • 端末はiPhone 5(iOS 8.4.1)
  • Debugビルドで実機に転送、デバッグ自体はすぐに停止。
  • 実機に転送されたアプリを起動。
  • Labelに表示された結果を確認後、アプリを終了させる。
  • 10回ずつ計測。

結果

  • XamlC無効
    • 平均: 103.9 ms
    • 個別: 105, 103, 101, 104, 102, 105, 106, 110, 102, 101 (ms)
  • XamlC有効
    • 平均: 19 ms
    • 個別: 19, 18, 36, 16, 16, 19, 16, 16, 18, 16 (ms)

InitializeComponent() にかかる時間がおよそ1/5に短縮されました!
かなり効果があると言えるでしょう。

複雑なXAMLであればより大きな差になるでしょう。しかし、レイアウト自体は実行時に行われるため、座標計算などのオーバーヘッドにはXamlCの効果が及ばない点に注意が必要です。

おまけ:C#で書いた場合

ついでにC#オンリーで書いた場合のタイムも計測してみました。

public CsPage()
{
	var stopwatch = Stopwatch.StartNew();
	Content = new Label();
	stopwatch.Stop();
	((Label)Content).Text = stopwatch.ElapsedMilliseconds + "ms";
}

結果

  • C#オンリー
    • 平均: 15.6 ms
    • 個別: 15, 15, 15, 15, 19, 15, 15, 15, 16, 16 (ms)

XamlCを有効にした場合よりも少し速いのはコードの違いか、何かしら最適化が働いているのか...

まとめ

  • 高速化はかなり有効、C#で書いた場合に迫る速度になる。
  • XAML記述サポートとして期待するにはもう一歩踏み込んだ解析能力が必要。(XamlC本来の目的ではない)
  • ぶっちゃけ全部C#で書くと速い。

参考

Xamarin.Forms 1.5.1-pre1 Released - Xamarin Forums

Xamarin.Forms 1.4.3-pre2 Released - Xamarin Forums

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?