「性能最適化1.1」計算方法の実行時間


「性能最適化1.0」起動分類及び起動時間の測定「性能最適化1.1」算出方法の実行時間
一、計算方法の実行時間
前のブログでは、アプリケーションの起動時間をどのように取得するかを分析しました.起動中に最適化できる方向がApplicationとActivityのライフサイクルであることも知っています.では、起動中に各メソッドを呼び出す実行時間を計算します.
1.1、一般方案
手動でポイントを埋め込む方法は、メソッドの実行前と実行後にポイントを埋め込み、この2つのポイントの時間差を計算するだけで、アプリケーションの開始時間を取得するのと同じ原理です.
具体的な埋め込み点実装は以下のコードに示すように,ApplicationではonCreateメソッドで多くの初期化メソッドが呼び出され,埋め込み点によって各呼び出しメソッドの内部でそのメソッドの時間消費時間を計算する.
//Application.java
@Override
public void onCreate() {
    initImageLoader();
    initBugly();
    initSharedPreference();
    //.....
}

private void initImageLoader() {
    long startTime = System.currentTimeMillis();
    Fresco.initialize(this);
    Log.d(TAG, "initImageLoader cost :" + (System.currentTimeMillis() - startTime));

private void initBugly() {
    long startTime = System.currentTimeMillis();
    //init bugly
    Log.d(TAG, "initBugly cost :" + (System.currentTimeMillis() - startTime));    
}

private void initSharedPreference() {
    long startTime = System.currentTimeMillis();
    //init SharedPreference
    Log.d(TAG, "initSharedPreference cost :" + (System.currentTimeMillis() - startTime));    
}

以上の方法は私たちが最初に考えた実現方法であるが、欠点も明らかである.
  • コードは優雅ではなく、それぞれの方法で埋め込む必要があります.
  • はプロジェクトへの侵入性が大きく,作業量も大きい.

  • 1.2、AOP方式で取得
    1.2.1、基本概念
    AOPは私たちがよく言う で、 に対して を行うことができます.
    次に、AOPによって、Applicationの各方法の実行時間を優雅に取得する.
    1.2.2、AspectJ導入
    AndroidではAspectJというライブラリでAOPを使用し、次にこのライブラリを導入します.
  • 工事ルートでbuild.gradleにAspectJプラグイン
  • を導入
    classpath ‘com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4’
  • はbuild.gradleアプリケーションプラグイン
  • apply plugin: ‘android-aspectjx’
  • はbuild.gradleにaspectjライブラリ
  • を導入
    implementation ‘org.aspectj:aspectjrt:1.8.9’
    以上のステップで、私たちは迅速にAspectJというライブラリにアクセスしました.
    1.2.3、具体的な使用
  • クラスPerformanceAopを定義@Aspect注記
  • を使用
  • @Around(「execution(*com.example.perfermance.aop.MyApplication.*)」)は、MyApplicationの各メソッドについてhook処理を行う必要があることを示します.
  • は、方法の実行前後のタイムスタンプを記録し、対応する時間差を計算する.

  • 注意:AspectJの詳細な使用については、読者はネット上で資料を調べることができ、現在、筆者は計算方法の時間のかかる計算を実現しているだけで、詳細な操作は分析を展開していない.
    @Aspect
    public class PerformanceAop {
    
        private static final String TAG = PerformanceAop.class.getSimpleName();
    
        @Around("execution(* com.example.perfermance.aop.MyApplication.**(..))")
        public void getTime(ProceedingJoinPoint joinPoint) {
            Signature signature = joinPoint.getSignature();
            //       ,  :MyApplication.attachBaseContext(..)
            String name = signature.toShortString();
            //           
            long startTime = System.currentTimeMillis();
    
            try {
                //     
                joinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            //          
            long costTime = System.currentTimeMillis() - startTime;
    
            Log.e(TAG, "method " + name + " cost:" + costTime);
        }
    }
    

    プログラムの実行結果:
    2019-03-17 20:29:12.946 10094-10094/com.example.perfermance E/PerformanceAop: method MyApplication.attachBaseContext(..) cost:1
    2019-03-17 20:29:12.979 10094-10094/com.example.perfermance E/PerformanceAop: method MyApplication.initBugly() cost:12
    2019-03-17 20:29:13.002 10094-10094/com.example.perfermance E/PerformanceAop: method MyApplication.initImageLoader() cost:23
    2019-03-17 20:29:13.002 10094-10094/com.example.perfermance E/PerformanceAop: method MyApplication.onCreate() cost:35
    

    二、まとめ
    本論文では,主に従来の方式とAOPの方式から方法の時間消費計算を計算したが,従来の実装スキームではコードが優雅ではなく,各方法に埋め込み点が必要であり,プロジェクトへの侵入性が大きく,作業量も大きいことが分かった.AOPという方式は比較的優雅な方式で実現され、既存のコードに対して侵入性がゼロであり、修正も便利である.
    2019年3月17日に記録