这天群里面大家都闲的时候,某君开始吐槽 Android 上的 UC 游览器,说以前版本的有多么快,现在的内存占用多大、多卡。一看到这个话题我就十分感兴趣,于是我就来胡扯一下 Android 上的程序效率问题,非专业文章,不喜勿看。
说起 Android 程序开发,可谓是又爱又恨。想想我们当年写对应的项目开发的时候,是有多复杂就往复杂里面写。后面实实在在接触了 CPP,然后会了析构,才发现 Java 的性能,就算发展 10 年,也赶不上 C、CPP,然后对于 UC 的内存占用和效率就释然了。
Android 程序用的是 Java,底层的 JVM(Java 虚拟机)其实是用 C 写的。╮(╯▽╰)╭ 一想到这个,我很多时候就非常想笑。用一个性能优秀一点的语言 Target 指定,然后解析一个性能差一点的语言的字节码,这也算是跨平台的硬伤吧,这就和 python 说自己比 C 还要快一样是个冷笑话。
而其实,解释一下跨平台和不跨平台的区别,你就能对于很多程序的性能就释然了。学过编译原理的可能会知道,一般指定平台的程序的编译流程是:词法分析->语法分析->语义分析->中间代码生成->中间代码优化->目标代码生成。
于是,程序在编译过程中会针对目标的平台进行相关优化,这样子的优点是程序的性能可能会更好,因为不同的平台可能说的指令集和中断调度算法都不一样,所以说编译程序时指定平台效率更高。(这里面细节我有兴趣时再说,涉及细节的计算机体系结构方面的知识。)
Java 一类的跨平台语言,比如还有 python,其本身的语法结构其实差不多,尤其在数据类型那边,基本一致。(因为编程语言的规范基本也就是 IEEE、MIT、ECMA 规定)它们的设计思想基本是编译到完整编译过程的中间代码部分,中间代码是平台无关的,一般是二进制文件。然后在通过平台相关的虚拟机运行中间代码。所以说 Java 是跨平台的,Java 虚拟机不是。或者说 Android 程序是跨平台的,但是 Android 系统不是。(正因为这一点,也导致了 Android 程序的反汇编很容易,破解也就自然不难了,目前大一点的 Android 程序都要混淆加密,虽然破解难度上升,但不是不能破解,只是运行效率不提也罢。)
由于硬件架构、硬件芯片不同。(也就是解决方案不同,MTK 是完整打包整板,但是高通不是)不同手机之间的 Android 系统要指定编译。尤其是在目前开发基本用交叉编译的时候,对应的虚拟机部分其实也是有区别优化的。所以,所谓的 Android 深度定制,其实本质就是对虚拟机进行指定平台相关的优化。
反过来继续说 Android 程序,因为为了跨平台,所以需要涉及虚拟机。一般的虚拟机都是用 C 写的,本身虚拟机也为了最大化兼容,已经丧失了一定的效率。然后再用这样子的低效率运行一个更加低效率的程序,这就是 Android 程序的本质无奈。
所以外界永远不知道的一个我们程序员的真相就是,我们永远是在为未来写代码。因为我们的代码永远不可能高效最优,一个软件写得越久,就会越来越冗余,越来越低效。然后我们就会把责任推给硬件,然后硬件就发展了。然后大家就一直买新的设备,我们就乐得写越来越低效的软件。
但是,这点在中国有点行不通。因为大家基本都是穷屌丝,一台手机不可能年抛,基本要用上个几年。所以才有了优化在中国的兴起。所以小米才会以优化定制为乐。但是这个的本质还是不行的,小米以后手机出得越多,架构越复杂的时候,它的优化也就越来越难做。而做 APP 开发的也很难做,一个是你的程序肯定会越做越复杂。目前的 Android 应用开发模式基本是 Scum 敏捷开发而不是以前的瀑布流,周期短,但是更新频繁。所以,你所面对的程序优化就越来越难做。
程序写复杂了,运行起来必定比以前慢,然后那群消费者就不干了。没错,新手机运行很流畅,很好,我们这群老用户呢?然后就一群人开始骂骂咧咧,然后应用站就开始刷新应用好卡、好慢、好烂,负分、差评、滚粗。而其实 Android 的开发门槛真的很低,做的基本是大专和本科,核心的优化有真的不行。所以垃圾应用铺天盖地都是,然后不赚钱,于是,有技术的也都懒得做了。
所以说,在天朝硬件想换代,难。所以逼着我们写垃圾代码,写低效率软件,然后逼着你换代升级。(微软的 Windows 就是一个典型的例子。)