2017年6月13日

前言

  前几日在改Bug时看到好多调试时用的日志语句都被一个日志开关控制着它的执行权。形如:

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

又为了方便日后遇到问题时的分析,还要加上很多类似的日志语句。这时突然很好奇“大量的”条件判断语句需要多消耗多少系统资源,以及不同的条件表达式占用系统资源的差异情况。为此,特意设计了一个简单的小实验,通过取多组不同环境下这几种情形的耗时均值作为考量依据。

设计实验

  对指定的条件语句进行一亿次的运算,计算运算前后的时间差作为结果。

  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 主要代码

     private final String TAG = "chorm";

     private final int chorm = 100000000;// 1亿
private boolean fieldBool;
private final boolean fieldBool2 = false;
private static boolean B3 = false;
private final static boolean B4 = false; private long getTime() {
return SystemClock.uptimeMillis();
} public void click(View v) {
int counter; Log.i(TAG, "- Prebuilt -");
counter = chorm;
long start = getTime();
do {
counter--;
} while (counter > 0);
long end = getTime(); Log.i(TAG, " - Demo begin -");
// 1. 一亿次循环运算空跑的耗时情况;
counter = chorm;
start = getTime();
do {
counter--;
} while (counter > 0);
end = getTime();
Log.d(TAG, "1:Time spent:" + (end - start) + "ms"); // 2. if语句条件表达式为简单运算的情况的耗时情况;
counter = chorm;
start = getTime();
do {
counter--;
if ((9 + 17) == 8) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "2:Time spent:" + (end - start) + "ms"); // 3. if语句条件表达式为局部boolean且值为true;
counter = chorm;
boolean localBool = true;
start = getTime();
do {
counter--;
if (localBool) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "3:Time spent:" + (end - start) + "ms"); // 4. if语句条件表达式为局部boolean且值为false;
counter = chorm;
localBool = false;
start = getTime();
do {
counter--;
if (localBool) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "4:Time spent:" + (end - start) + "ms"); // 5. if语句条件表达式为局部final boolean且值为false;
counter = chorm;
final boolean localBool2 = false;
start = getTime();
do {
counter--;
if (localBool2) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "5:Time spent:" + (end - start) + "ms"); // 6. if语句条件表达式为全局boolean且值为false;
counter = chorm;
start = getTime();
do {
counter--;
if (fieldBool) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "6:Time spent:" + (end - start) + "ms"); // 7. if语句条件表达式为全局final boolean且值为false;
counter = chorm;
start = getTime();
do {
counter--;
if (fieldBool2) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "7:Time spent:" + (end - start) + "ms"); // 8. if语句条件表达式为另一个类对象中的实例变量boolean且值为false;
counter = chorm;
AnotherClass ac = new AnotherClass();
start = getTime();
do {
counter--;
if (ac.bool) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "8:Time spent:" + (end - start) + "ms"); // 9. if语句条件表达式为另一个类对象中的静态变量boolean且值为true;
counter = chorm;
start = getTime();
do {
counter--;
if (AnotherClass.BOOL) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "9:Time spent:" + (end - start) + "ms"); // 10. if语句条件表达式为另一个类对象中的静态变量boolean且值为false;
counter = chorm;
start = getTime();
do {
counter--;
if (AnotherClass.BOOL2) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "10:Time spent:" + (end - start) + "ms"); // 11. if语句条件表达式为另一个类对象中的静态final变量boolean且值为true;
counter = chorm;
start = getTime();
do {
counter--;
if (AnotherClass.BOOL3) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "11:Time spent:" + (end - start) + "ms"); // 12. if语句条件表达式为另一个类对象中的静态final变量boolean且值为false;
counter = chorm;
start = getTime();
do {
counter--;
if (AnotherClass.BOOL4) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "12:Time spent:" + (end - start) + "ms"); // 13. if语句条件表达式为静态final变量boolean且值为false;
counter = chorm;
start = getTime();
do {
counter--;
if (B4) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "13:Time spent:" + (end - start) + "ms"); // 14. if语句条件表达式为静态变量boolean且值为false;
counter = chorm;
start = getTime();
do {
counter--;
if (B3) { }
} while (counter > 0);
end = getTime();
Log.d(TAG, "14:Time spent:" + (end - start) + "ms"); Log.v(TAG, " - Demo end -");
}

AnotherClass.java

 public class AnotherClass {
public static boolean BOOL = true;
public static boolean BOOL2 = false;
public static final boolean BOOL3 = true;
public static final boolean BOOL4 = false;
public boolean bool;
}

实验结果

  共进行了五个不同环境下的测试实验。

    第一组:开机后在首页

    第二组:打开了很多应用以后

    第三组:播放数字电视节目时启动测试应用。

    第四组:播放一段4K视频时启动测试应用。

    第五组:在首页启动测试应用。

    第六组:在首页启动测试应用。

                       单位:毫秒(ms)

序号 第一组 第二组 第三组 第四组 第五组 第六组 耗时均值  
1 347  345.5  
2 347  359  347  344  345  347.67  
3 346  348  346  345  344  345.5  
4 346  347  345  344  344  345  
5 347  346  346  344  344  345  345.17  
6 347  346  345  345  344  344  345.17  
7 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.33  
11 344.5  
12 347.83  
13 346  
14 345.17  

结论

  • 对于if语句条件表达式的耗时应以条件结果为false的为准。
  • 大多数情况下条件判断所耗时间相当。
  • 当条件被判断为true时(对比3、4),即时后面的方法体是空的,也需要更多的时间来执行,对比9、10的结果更明显。
  • 非必须条件下不要在条件判断语句处作运算(结果2),尽可能地将运算过程放在编译时来执行。
  • 变量是否被final修饰似乎对结果没有什么影响(4、5与6、7),事实上这个结果让我也很迷惑。不排除是我的测试环境与测试方法的问题。
  • 变量定义在哪一个对象对结果没有什么影响(结果6、结果8 )
  • 对于另一个类对象中的静态变量,所花费的时间相较于其它情况长很多(结果9、结果10)。尽量不要使用其它类对象中的非final静态变量。

  我相信没什么应用的调试日志数量能达到1亿条或者更多。即使是1410.33毫秒,分成1亿份,它的时间也是微不足道的,并且市面上移动设备处理器通常都比我手里这块要好。因此,实际结论是:你想怎样用就怎样用。当然,日志打印的耗时情况就不在我们的讨论范围之内了。

简单探究Android平台下' if ' 语句条件判断耗时情况的更多相关文章

  1. [转帖]Android平台下OpenGL初步

    原文请看 Android平台下OpenGL初步 本文只关注于如何一步步实现在Android平台下运用OpenGl. 1.GLSurfaceView GLSurfaceView是Android应用程序中 ...

  2. Android平台下的TCP/IP传输(客户端)

    在工科类项目中,嵌入式系统与软件系统或后台数据库之间的信息传输是实现“物联网”的一种必要的途径,对已简单概念的物联网,通常形式都是一个单片机/嵌入式系统实现数据的采集及其处理,通过蓝牙,wifi或者是 ...

  3. Android平台下Dalvik层hook框架ddi的研究

    通过adbi,可以对native层的所有代码进行hook.但对于Android系统来说,这还远远不够,因为很多应用都还是在Dalvik虚拟机中运行的. 那么,有没有什么办法可以对Dalvik虚拟机中跑 ...

  4. Android平台下OpenCV移植与使用---基于C/C++

    在<Android Studio增加NDK代码编译支持--Mac环境>和<Mac平台下Opencv开发环境搭建>两篇文章中,介绍了如何使用NDK环境和Opencv环境搭建与测试 ...

  5. Android平台下OpenGL初步

    Android OpenGL ES 开发教程 从入门到精通 http://blog.csdn.net/zhoudailiang/article/details/50176143 http://blog ...

  6. Android平台下OpenGL图形编程

    ref: Jayway Team Blog中OpenGL ES简明开发教程https://blog.jayway.com/tag/opengl-es/ OpenGL ES 开发教程http://www ...

  7. Android平台下的JNI开发

    JNI是Java Native Interface的缩写,通过JNI可以方便我们在Android平台上进行C/C++编程.要用JNI首先必须安装Android的NDK,配置好NDK环境之后就可以在Ec ...

  8. <2014 05 14> Android平台下2D/3D开发攻略

    Android通过OpenGL包含了对高性能2D和3D图形的支持,尤其支持OpenGLES API.OpenGL是一个跨平台的图形API,提供了软件操作3D图形硬件的接口.OpenGLES是一个专用于 ...

  9. Android 平台下Cordova 调用Activity插件开发

    首先建立一个包名为package com.JiajiaCy.CallActivity; package com.JajaCy.CallActivity; import org.apache.cordo ...

随机推荐

  1. List对象去重碎碎念之神叨叨

    前言 List集合操作去除重复数据的这种情况经常会碰到,博客园里面也有很多大神们做过,在这里主要是借鉴然后自己整理了一下,主要是为了方便自己,以后再次碰到这种去重问题,直接打开自己的链接拿起键盘就是干 ...

  2. urllib爬虫(流程+案例)

    网络爬虫是一种按照一定规则自动抓取万维网信息的程序.在如今网络发展,信息爆炸的时代,信息的处理变得尤为重要.而这之前就需要获取到数据.有关爬虫的概念可以到网上查看详细的说明,今天在这里介绍一下使用ur ...

  3. zabbix安装与配置

    一.什么是zabbix及优缺点(对比cacti和nagios) Zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题.是一个基于WE ...

  4. Python_老男孩练习题1

    get有陷阱:value   5.以下打印的内容是:——————    ——————    —————— [10, 'a'] [123] [10, 'a'] #方法一: 将list 转为 set #l ...

  5. Python_列表推导式_生成器的表达式_各种推导式_40

    列表推导式: #列表推导式: egg_list = [] for i in range(10): egg_list.append('鸡蛋%s'%i) print(egg_list) egon egg_ ...

  6. HDU - 4027 线段树减枝

    这题太坑了...满满的都是坑点 1号坑点:给定左右区间有可能是反的...因为题目上说x,y之间,但是没有说明x,y的大小关系(害我一直RE到怀疑人生) 2号坑点:开根号的和不等于和开根号(还好避开了) ...

  7. 分解质因数FZU - 1075

    题目简述:就是给一个数,把他拆分成多个素数的乘积,这正好是算术基本定理.本题我的解决方法是埃氏素数筛+质因数保存...开始T掉了,是因为我在最后枚举了素数,保存他们的次数,然后两次for去查询他们的次 ...

  8. Innodb日志与事务

    1.Innodb日志: 错误日志:记录出错信息,也记录一些警告信息或者正确的信息. 查询日志:记录所有对数据库请求的信息,不论这些请求是否得到了正确的执行. 慢查询日志:设置一个阈值,将运行时间超过该 ...

  9. 逻辑回归为什么用sigmoid函数

    Logistic回归目的是从特征学习出一个0/1分类模型,而这个模型是将特性的线性组合作为自变量,由于自变量的取值范围是负无穷到正无穷. 因此,使用logistic函数(或称作sigmoid函数)将自 ...

  10. How To: Capture Android & iOS Traffic with Fiddler

    How To: Capture iOS Traffic with Fiddlerhttps://www.telerik.com/blogs/how-to-capture-ios-traffic-wit ...