Android L に採用されるARTってどんだけすごいの?
本日のGoogle I/Oで、次期バージョンのAndroid L に新VMとしてARTを採用すると発表していました。
ARTって何?って感じだったので、実際に触って検証してみました。
KitKat (android 4.4)でART
実はARTは KitKat (android 4.4)で試験的に実装されていたんですね!(知らなかった。。。) ということで、実機を使って検証してみました。
ARTに切り替え
KitKat で ARTに切り替える場合は、「開発者向けオプション」の「ランタイムを選択」から「ARTを使用」を選択すれば切り替わります。
切り替える際は、再起動が行われ、5分ほどかかります。
検証
ツールを使用したベンチマークテストや、動画での動作比較などはすでにいろいろと実施されていましたので、今回は実際にコードを実行して、何msくらい差がでるのか、という検証をしてみました。 正直、実機ではバックグランド処理などの影響で結果が変わるので、この検証に意味があるのかわかりませんが、一応ある程度の差が出たので、記述したいと思います。
内容
簡単なサンプルアプリを作成し、1024x768サイズの画像を表示する際の時間を計測してみました。 ボタンを押したら、8枚の画像が表示されるだけです。(スクリーンショットではわからないのですが、スクロールになっています。)
細かい内容としては、ボタンを押してから、Bitmap を生成し、ImageViewにセットする(x8回)までを計測しました。(8回というのは特に意味はありません。)
50回繰り返したデータが以下のようになりました。
ARTとDalvikの平均結果は以下のようになりました。
ART 平均 | 361.66[ms] |
Dalvik 平均 | 414.3[ms] |
ARTの方が約1.14倍速い!
今回の結果では、imageViewのみの検証だったからか、爆速!という程の変化はありませんでした。が、確かに速くはなりました。
実際には、演算処理などの方が違いがわかりやすいようです。
まだ開発者用のARTで実施したので、製品版ではさらに早くなっているかもしれませんね。
というところで、今回の検証は以上です。
ちなみに以下が、今回検証に使用したソースコードです。(参考にはならないと思いますが。。。) もっとこうした方が正確な値が計測しやすい!などありましたらご教授いただけると幸いです。
public class MainActivity extends Activity { private static final String TAG = MainActivity.class.getSimpleName(); private ImageView mImageView1; private ImageView mImageView2; private ImageView mImageView3; private ImageView mImageView4; private ImageView mImageView5; private ImageView mImageView6; private ImageView mImageView7; private ImageView mImageView8; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mImageView1 = (ImageView)findViewById(R.id.imageView1); mImageView2 = (ImageView)findViewById(R.id.imageView2); mImageView3 = (ImageView)findViewById(R.id.imageView3); mImageView4 = (ImageView)findViewById(R.id.imageView4); mImageView5 = (ImageView)findViewById(R.id.imageView5); mImageView6 = (ImageView)findViewById(R.id.imageView6); mImageView7 = (ImageView)findViewById(R.id.imageView7); mImageView8 = (ImageView)findViewById(R.id.imageView8); Button button1 = (Button)findViewById(R.id.button1); button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { long before = System.currentTimeMillis(); Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.chrysanthemum); mImageView1.setImageBitmap(bitmap1); Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.desert); mImageView2.setImageBitmap(bitmap2); Bitmap bitmap3 = BitmapFactory.decodeResource(getResources(), R.drawable.hydrangeas); mImageView3.setImageBitmap(bitmap3); Bitmap bitmap4 = BitmapFactory.decodeResource(getResources(), R.drawable.jellyfish); mImageView4.setImageBitmap(bitmap4); Bitmap bitmap5 = BitmapFactory.decodeResource(getResources(), R.drawable.koala); mImageView5.setImageBitmap(bitmap5); Bitmap bitmap6 = BitmapFactory.decodeResource(getResources(), R.drawable.lighthouse); mImageView6.setImageBitmap(bitmap6); Bitmap bitmap7 = BitmapFactory.decodeResource(getResources(), R.drawable.penguins); mImageView7.setImageBitmap(bitmap7); Bitmap bitmap8 = BitmapFactory.decodeResource(getResources(), R.drawable.tulips); mImageView8.setImageBitmap(bitmap8); long after = System.currentTimeMillis(); long diff = after - before; Log.d(TAG, "diff = " + diff); } }); }