Jetpack Composeは速い？遅い？

この記事は [Android Advent Calendar 2019](https://qiita.com/advent-calendar/2019/android)10日目の記事です。
これまでの有益な記事たちと違って、非常に駄文めいているので気休めでご覧ください。


Android Studio 4.0でJetpack Composeが使用可能になりました。
Jetpack Composeを使用することでUIをKotlin上から宣言的に記載することができます。

さて、Jetpack Composeといえば思い出されるのがAnkoで、これもKotlin上から宣言的にUIを記載するもの
そのときによく言われていたのが ANKOはXMLをパースしないので性能面で有利ということ。

ではJetpack Composeではどうなのでしょう。

ここでは以下の環境でJetpack Composeと従来的なxmlを使ったViewの速度比較をしてみます。

# 環境は次の通り
Android Studio 4.0 Canary 4
Kotlin 1.3.60-eap-25
androidx.ui:ui-layout:0.1.0-dev02

単純にTextViewを10件並べたものを用意してみます。
アプリの測定時間はLogcatの Displayed の時間をもとに測定。
実行環境はAPI28のエミュレータで、MacBookPro 13インチ上で実行しています。

計測は10回繰り返し、その平均と最遅、最速を取得しています。
# Jetpack Compose

Activity上でTextを10個並べます

``` Kotlin
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {

                Column {
                    Text(text = "Hello Android!")
                    Text(text = "Hello Android!")
                    Text(text = "Hello Android!")
                    Text(text = "Hello Android!")
                    Text(text = "Hello Android!")
                    Text(text = "Hello Android!")
                    Text(text = "Hello Android!")
                    Text(text = "Hello Android!")
                    Text(text = "Hello Android!")
                    Text(text = "Hello Android!")
                }
        }
    }
```
## 結果
単位 ms
864
958
896
848
932
929
879
895
1255
828
最遅 1255
平均 928.4
最速 828

#Linear Layout

``` XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" />
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" />
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" />
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" />
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" />
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" />
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" />
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" />
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" />
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" />
</LinearLayout>
```
## 結果
単位 ms
497
610
590
576
643
639
684
482
594
500
最遅 684
平均 581.5
最速 482


#Constraint Layout
``` XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" />
    <TextView android:id="@+id/text2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/text1" />
    <TextView android:id="@+id/text3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/text2" />
    <TextView android:id="@+id/text4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/text3" />
    <TextView android:id="@+id/text5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/text4" />
    <TextView android:id="@+id/text6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/text5" />
    <TextView android:id="@+id/text7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/text6" />
    <TextView android:id="@+id/text8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/text7" />
    <TextView android:id="@+id/text9" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/text8" />
    <TextView android:id="@+id/text10" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello Android!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/text9" />
    
</androidx.constraintlayout.widget.ConstraintLayout>
```
## 結果
597
555
604
592
576
549
567
666
551
652
最遅 666
平均 590.9
最速 549

# 比較
結果を比較してみます。

|測定結果|Jetpack Compose  |Linear Layout  |Constraint Layout  |
|---|---|---|---|
|最遅|1255  |684  |666  |
|平均|928.4  |581.5  |590.9  |
|最速|828|482 |594|
予想に反して、Jetpack Composeが一番遅いという結果になってしまいました。
最速の場合でさえ、Linear LayoutやConstraint Layoutの最遅より遅いです。

Linear Layoutはさすがの最速を決めました。
ただし、このレイアウトはLinear Layoutに特化したレイアウトであることに注意が必要で、Linear Layoutはその性質上、複雑なレイアウトを作れないというのには注意が必要です。

その点、意外な好成績だったのがConstraint LayoutでLinear Layoutとほとんど性能差がないという結果に

Jetpack Composeはまだdev02でパフォーマンス改善に手がつけられていないという可能性はあり今後この数値は逆転するかもしれませんが、現状では性能を考えるとシンプルなレイアウトはFramelayoutやLinearLayoutを使い、複雑なページはConstraint Layoutを使うのが良さそう。
性能面を理由にJetpack Composeを使う理由はなさそうです。