簡單探究Android平台下' if ' 語句條件判斷耗時情況


2017年6月13日

前言

  前幾日在改Bug時看到好多調試時用的日志語句都被一個日志開關控制着它的執行權。形如:

1 if(Constants.LOG_TAG){
2     Log.d(TAG, "Initialize finish! index:" + idx);
3 }

又為了方便日后遇到問題時的分析,還要加上很多類似的日志語句。這時突然很好奇“大量的”條件判斷語句需要多消耗多少系統資源,以及不同的條件表達式占用系統資源的差異情況。為此,特意設計了一個簡單的小實驗,通過取多組不同環境下這幾種情形的耗時均值作為考量依據。

 

設計實驗

  對指定的條件語句進行一億次的運算,計算運算前后的時間差作為結果。

  1. 一億次循環運算空跑的耗時情況;
  2. if語句條件表達式為簡單運算的情況的耗時情況;
  3. if語句條件表達式為局部boolean且值為true;
  4. if語句條件表達式為局部boolean且值為false;
  5. if語句條件表達式為局部final boolean且值為false;
  6. if語句條件表達式為全局boolean且值為false;
  7. if語句條件表達式為全局final boolean且值為false;
  8. if語句條件表達式為另一個類對象中的實例變量boolean且值為false;
  9. if語句條件表達式為另一個類對象中的靜態變量boolean且值為true;
  10. if語句條件表達式為另一個類對象中的靜態變量boolean且值為false;
  11. if語句條件表達式為另一個類對象中的靜態final布爾變量且值為true;
  12. if語句條件表達式為另一個類對象中的靜態final布爾變量且值為false;
  13. if語句條件表達式為靜態final變量boolean且值為false;
  14. if語句條件表達式為靜態變量boolean且值為false;

 

實驗環境

  操作系統:Android 5.1

  設備系統:4K智能電視

  處理器:Hi3751v620

  內存:2GB

 

代碼設計

MainActivity.java 主要代碼

  1     private final String TAG = "chorm";
  2 
  3     private final int chorm = 100000000;// 1億
  4     private boolean fieldBool;
  5     private final boolean fieldBool2 = false;
  6     private static boolean B3 = false;
  7     private final static boolean B4 = false;
  8 
  9     private long getTime() {
 10         return SystemClock.uptimeMillis();
 11     }
 12 
 13     public void click(View v) {
 14         int counter;
 15 
 16         Log.i(TAG, "- Prebuilt -");
 17         counter = chorm;
 18         long start = getTime();
 19         do {
 20             counter--;
 21         } while (counter > 0);
 22         long end = getTime();
 23 
 24         Log.i(TAG, " - Demo begin -");
 25         // 1. 一億次循環運算空跑的耗時情況;
 26         counter = chorm;
 27         start = getTime();
 28         do {
 29             counter--;
 30         } while (counter > 0);
 31         end = getTime();
 32         Log.d(TAG, "1:Time spent:" + (end - start) + "ms");
 33 
 34         // 2. if語句條件表達式為簡單運算的情況的耗時情況;
 35         counter = chorm;
 36         start = getTime();
 37         do {
 38             counter--;
 39             if ((9 + 17) == 8) {
 40 
 41             }
 42         } while (counter > 0);
 43         end = getTime();
 44         Log.d(TAG, "2:Time spent:" + (end - start) + "ms");
 45 
 46         // 3. if語句條件表達式為局部boolean且值為true;
 47         counter = chorm;
 48         boolean localBool = true;
 49         start = getTime();
 50         do {
 51             counter--;
 52             if (localBool) {
 53 
 54             }
 55         } while (counter > 0);
 56         end = getTime();
 57         Log.d(TAG, "3:Time spent:" + (end - start) + "ms");
 58 
 59         // 4. if語句條件表達式為局部boolean且值為false;
 60         counter = chorm;
 61         localBool = false;
 62         start = getTime();
 63         do {
 64             counter--;
 65             if (localBool) {
 66 
 67             }
 68         } while (counter > 0);
 69         end = getTime();
 70         Log.d(TAG, "4:Time spent:" + (end - start) + "ms");
 71 
 72         // 5. if語句條件表達式為局部final boolean且值為false;
 73         counter = chorm;
 74         final boolean localBool2 = false;
 75         start = getTime();
 76         do {
 77             counter--;
 78             if (localBool2) {
 79 
 80             }
 81         } while (counter > 0);
 82         end = getTime();
 83         Log.d(TAG, "5:Time spent:" + (end - start) + "ms");
 84 
 85         // 6. if語句條件表達式為全局boolean且值為false;
 86         counter = chorm;
 87         start = getTime();
 88         do {
 89             counter--;
 90             if (fieldBool) {
 91 
 92             }
 93         } while (counter > 0);
 94         end = getTime();
 95         Log.d(TAG, "6:Time spent:" + (end - start) + "ms");
 96 
 97         // 7. if語句條件表達式為全局final boolean且值為false;
 98         counter = chorm;
 99         start = getTime();
100         do {
101             counter--;
102             if (fieldBool2) {
103 
104             }
105         } while (counter > 0);
106         end = getTime();
107         Log.d(TAG, "7:Time spent:" + (end - start) + "ms");
108 
109         // 8. if語句條件表達式為另一個類對象中的實例變量boolean且值為false;
110         counter = chorm;
111         AnotherClass ac = new AnotherClass();
112         start = getTime();
113         do {
114             counter--;
115             if (ac.bool) {
116 
117             }
118         } while (counter > 0);
119         end = getTime();
120         Log.d(TAG, "8:Time spent:" + (end - start) + "ms");
121 
122         // 9. if語句條件表達式為另一個類對象中的靜態變量boolean且值為true;
123         counter = chorm;
124         start = getTime();
125         do {
126             counter--;
127             if (AnotherClass.BOOL) {
128 
129             }
130         } while (counter > 0);
131         end = getTime();
132         Log.d(TAG, "9:Time spent:" + (end - start) + "ms");
133 
134         // 10. if語句條件表達式為另一個類對象中的靜態變量boolean且值為false;
135         counter = chorm;
136         start = getTime();
137         do {
138             counter--;
139             if (AnotherClass.BOOL2) {
140 
141             }
142         } while (counter > 0);
143         end = getTime();
144         Log.d(TAG, "10:Time spent:" + (end - start) + "ms");
145 
146         // 11. if語句條件表達式為另一個類對象中的靜態final變量boolean且值為true;
147         counter = chorm;
148         start = getTime();
149         do {
150             counter--;
151             if (AnotherClass.BOOL3) {
152 
153             }
154         } while (counter > 0);
155         end = getTime();
156         Log.d(TAG, "11:Time spent:" + (end - start) + "ms");
157 
158         // 12. if語句條件表達式為另一個類對象中的靜態final變量boolean且值為false;
159         counter = chorm;
160         start = getTime();
161         do {
162             counter--;
163             if (AnotherClass.BOOL4) {
164 
165             }
166         } while (counter > 0);
167         end = getTime();
168         Log.d(TAG, "12:Time spent:" + (end - start) + "ms");
169         
170         // 13. if語句條件表達式為靜態final變量boolean且值為false;
171         counter = chorm;
172         start = getTime();
173         do {
174             counter--;
175             if (B4) {
176                 
177             }
178         } while (counter > 0);
179         end = getTime();
180         Log.d(TAG, "13:Time spent:" + (end - start) + "ms");
181         
182         // 14. if語句條件表達式為靜態變量boolean且值為false;
183         counter = chorm;
184         start = getTime();
185         do {
186             counter--;
187             if (B3) {
188                 
189             }
190         } while (counter > 0);
191         end = getTime();
192         Log.d(TAG, "14:Time spent:" + (end - start) + "ms");
193 
194         Log.v(TAG, " - Demo end -");
195     }

 

AnotherClass.java

1 public class AnotherClass {
2     public static boolean BOOL = true;
3     public static boolean BOOL2 = false;
4     public static final boolean BOOL3 = true;
5     public static final boolean BOOL4 = false;
6     public boolean bool;
7 }

 

實驗結果

  共進行了五個不同環境下的測試實驗。

    第一組:開機后在首頁

    第二組:打開了很多應用以后

    第三組:播放數字電視節目時啟動測試應用。

    第四組:播放一段4K視頻時啟動測試應用。

    第五組:在首頁啟動測試應用。

    第六組:在首頁啟動測試應用。

                       單位:毫秒(ms)

序號 第一組 第二組 第三組 第四組 第五組 第六組 耗時均值  
1 347  344 348 346 344 344 345.5  
2 347  359  347  344  344 345  347.67  
3 346  348  346  345  344 344  345.5  
4 346  347  345  344  344 344  345  
5 347  346  346  344  344  345  345.17  
6 347  346  345  345  344  344  345.17  
7 346  346  346 344  344  344  345  
8 347  346  345  344  344  345  345.17  
9 2292  2277  2279  2268  2265  2264  2274.17  
10 1410 1411 1408 1411 1411 1411 1410.33  
11 345 345 344 345 344 344 344.5  
12 345 345 344 346 363 344 347.83  
13 346 345 350 345 345 345 346  
14 344 345 350 344 344 344 345.17  

 

結論

  • 對於if語句條件表達式的耗時應以條件結果為false的為准。
  • 大多數情況下條件判斷所耗時間相當。
  • 當條件被判斷為true時(對比3、4),即時后面的方法體是空的,也需要更多的時間來執行,對比9、10的結果更明顯。
  • 非必須條件下不要在條件判斷語句處作運算(結果2),盡可能地將運算過程放在編譯時來執行。
  • 變量是否被final修飾似乎對結果沒有什么影響(4、5與6、7),事實上這個結果讓我也很迷惑。不排除是我的測試環境與測試方法的問題。
  • 變量定義在哪一個對象對結果沒有什么影響(結果6、結果8 )
  • 對於另一個類對象中的靜態變量,所花費的時間相較於其它情況長很多(結果9、結果10)。盡量不要使用其它類對象中的非final靜態變量。

 

  我相信沒什么應用的調試日志數量能達到1億條或者更多。即使是1410.33毫秒,分成1億份,它的時間也是微不足道的,並且市面上移動設備處理器通常都比我手里這塊要好。因此,實際結論是:你想怎樣用就怎樣用。當然,日志打印的耗時情況就不在我們的討論范圍之內了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM