Android Performance Tips

本文提供了一系列针对Android应用的性能优化技巧,包括减少不必要的对象创建、使用静态方法而非虚拟方法、利用静态常量等实践,旨在帮助开发者提高应用程序的整体运行效率。

http://developer.android.com/training/articles/perf-tips.html


Performance Tips



1.      Avoid Creating Unnecessary Objects

2.      Prefer Static Over Virtual

3.      Use Static Final For Constants

4.      Avoid Internal Getters/Setters

5.      Use Enhanced For Loop Syntax

6.      Consider Package Instead of Private Access with Private Inner Classes

7.      Avoid Using Floating-Point

8.      Know and Use the Libraries

9.      Use Native Methods Carefully

10.  Use Native Methods Judiciously

11.  Closing Notes


In this document

This document primarily coversmicro-optimizations that can improve overall app performance when combined, butit's unlikely that these changes will result in dramatic performance effects.Choosing the right algorithms and data structures should always be yourpriority, but is outside the scope of this document. You should use the tips inthis document as general coding practices that you can incorporate into yourhabits for general code efficiency.

There are two basic rules for writingefficient code:

·        Don't do work that you don't need to do.

·        Don't allocate memory if you can avoid it.

One of the trickiest problems you'll facewhen micro-optimizing an Android app is that your app is certain to be runningon multiple types of hardware. Different versions of the VM running ondifferent processors running at different speeds. It's not even generally thecase that you can simply say "device X is a factor F faster/slower thandevice Y", and scale your results from one device to others. Inparticular, measurement on the emulator tells you very little about performanceon any device. There are also huge differences between devices with and withouta JIT: the best code for a device with a JIT isnot always the best code for a device without.

To ensure your app performs well across awide variety of devices, ensure your code is efficient at all levels andagressively optimize your performance.

Avoid CreatingUnnecessary Objects


Object creation is never free. Agenerational garbage collector with per-thread allocation pools for temporaryobjects can make allocation cheaper, but allocating memory is always moreexpensive than not allocating memory.

As you allocate more objects in your app,you will force a periodic garbage collection, creating little"hiccups" in the user experience. The concurrent garbage collectorintroduced in Android 2.3 helps, but unnecessary work should always be avoided.

Thus, you should avoid creating objectinstances you don't need to. Some examples of things that can help:

·        If you have a method returning a string, andyou know that its result will always be appended to a StringBuffer anyway, changeyour signature and implementation so that the function does the appenddirectly, instead of creating a short-lived temporary object.

·        When extracting strings from a set of inputdata, try to return a substring of the original data, instead of creating acopy. You will create a new String object, but itwill share the char[] with the data. (The trade-off being that ifyou're only using a small part of the original input, you'll be keeping it allaround in memory anyway if you go this route.)

A somewhat more radical idea is to slice upmultidimensional arrays into parallel single one-dimension arrays:

·        An array of ints is a muchbetter than an array of Integer objects, butthis also generalizes to the fact that two parallel arrays of ints are also a lot more efficient than an array of (int,int) objects. Thesame goes for any combination of primitive types.

·        If you need to implement a container thatstores tuples of (Foo,Bar) objects, try to remember that two parallel Foo[] and Bar[] arrays aregenerally much better than a single array of custom (Foo,Bar) objects. (Theexception to this, of course, is when you're designing an API for other code toaccess. In those cases, it's usually better to make a small compromise to thespeed in order to achieve a good API design. But in your own internal code, youshould try and be as efficient as possible.)

Generally speaking, avoid creatingshort-term temporary objects if you can. Fewer objects created meanless-frequent garbage collection, which has a direct impact on user experience.

Prefer Static OverVirtual


If you don't need to access an object'sfields, make your method static. Invocations will be about 15%-20% faster. It'salso good practice, because you can tell from the method signature that callingthe method can't alter the object's state.

Use Static Final ForConstants


Consider the following declaration at thetop of a class:

static int intVal = 42;
static String strVal = "Hello, world!";

The compiler generates a class initializermethod, called <clinit>, that is executed when the class is firstused. The method stores the value 42 into intVal, and extracts areference from the classfile string constant table for strVal. When thesevalues are referenced later on, they are accessed with field lookups.

We can improve matters with the"final" keyword:

static final int intVal = 42;
static final String strVal = "Hello, world!";

The class no longer requires a <clinit> method, becausethe constants go into static field initializers in the dex file. Code thatrefers to intVal will use the integer value 42 directly, andaccesses to strVal will use a relatively inexpensive"string constant" instruction instead of a field lookup.

Note: Thisoptimization applies only to primitive types and String constants, notarbitrary reference types. Still, it's good practice to declare constants static final wheneverpossible.

Avoid InternalGetters/Setters


In native languages like C++ it's commonpractice to use getters (i = getCount()) instead ofaccessing the field directly (i = mCount). This is anexcellent habit for C++ and is often practiced in other object orientedlanguages like C# and Java, because the compiler can usually inline the access,and if you need to restrict or debug field access you can add the code at anytime.

However, this is a bad idea on Android.Virtual method calls are expensive, much more so than instance field lookups.It's reasonable to follow common object-oriented programming practices and havegetters and setters in the public interface, but within a class you shouldalways access fields directly.

Without a JIT, direct field access is about 3x faster than invoking a trivial getter.With the JIT (where direct field access is as cheap as accessing a local),direct field access is about 7x faster than invoking a trivial getter.

Note that if you're using ProGuard, you can have the best of both worlds becauseProGuard can inline accessors for you.

Use Enhanced ForLoop Syntax


The enhanced for loop (alsosometimes known as "for-each" loop) can be used for collections thatimplement the Iterable interface andfor arrays. With collections, an iterator is allocated to make interface callsto hasNext() and next(). With an ArrayList, a hand-writtencounted loop is about 3x faster (with or without JIT), but for othercollections the enhanced for loop syntax will be exactly equivalent to explicititerator usage.

There are several alternatives for iteratingthrough an array:

static class Foo {
    int mSplat;
}

Foo[] mArray = ...

public void zero() {
    int sum = 0;
    for (int i = 0; i < mArray.length; ++i) {
        sum += mArray[i].mSplat;
    }
}

public void one() {
    int sum = 0;
    Foo[] localArray = mArray;
    int len = localArray.length;

    for (int i = 0; i < len; ++i) {
        sum += localArray[i].mSplat;
    }
}

public void two() {
    int sum = 0;
    for (Foo a : mArray) {
        sum += a.mSplat;
    }
}

zero() is slowest, becausethe JIT can't yet optimize away the cost of getting the array length once forevery iteration through the loop.

one() is faster. It pullseverything out into local variables, avoiding the lookups. Only the arraylength offers a performance benefit.

two() is fastest fordevices without a JIT, and indistinguishable from one() for devices with a JIT. It uses the enhanced for loopsyntax introduced in version 1.5 of the Java programming language.

So, you should use the enhanced for loop by default,but consider a hand-written counted loop for performance-critical ArrayList iteration.

Tip: Also see JoshBloch's Effective Java, item 46.

Consider PackageInstead of Private Access with Private Inner Classes


Consider the following class definition:

public class Foo {
    private class Inner {
        void stuff() {
            Foo.this.doStuff(Foo.this.mValue);
        }
    }

    private int mValue;

    public void run() {
        Inner in = new Inner();
        mValue = 27;
        in.stuff();
    }

    private void doStuff(int value) {
        System.out.println("Value is " + value);
    }
}

What's important here is that we define aprivate inner class (Foo$Inner) that directlyaccesses a private method and a private instance field in the outer class. Thisis legal, and the code prints "Value is 27" as expected.

The problem is that the VM considers directaccess to Foo's private members from Foo$Inner to be illegalbecause Foo and Foo$Inner are differentclasses, even though the Java language allows an inner class to access an outerclass' private members. To bridge the gap, the compiler generates a couple ofsynthetic methods:

/*package*/ static int Foo.access$100(Foo foo){
    return foo.mValue;
}
/*package*/ static void Foo.access$200(Foo foo, int value) {
    foo.doStuff(value);
}

The inner class code calls these staticmethods whenever it needs to access the mValue field or invokethe doStuff() method in the outer class. What this means is that thecode above really boils down to a case where you're accessing member fieldsthrough accessor methods. Earlier we talked about how accessors are slower thandirect field accesses, so this is an example of a certain language idiomresulting in an "invisible" performance hit.

If you're using code like this in aperformance hotspot, you can avoid the overhead by declaring fields and methodsaccessed by inner classes to have package access, rather than private access.Unfortunately this means the fields can be accessed directly by other classesin the same package, so you shouldn't use this in public API.

Avoid UsingFloating-Point


As a rule of thumb, floating-point is about2x slower than integer on Android-powered devices.

In speed terms, there's no differencebetween float and double on the moremodern hardware. Space-wise, double is 2x larger. Aswith desktop machines, assuming space isn't an issue, you should prefer double to float.

Also, even for integers, some processorshave hardware multiply but lack hardware divide. In such cases, integerdivision and modulus operations are performed in software—something to thinkabout if you're designing a hash table or doing lots of math.

Know and Use theLibraries


In addition to all the usual reasons toprefer library code over rolling your own, bear in mind that the system is atliberty to replace calls to library methods with hand-coded assembler, whichmay be better than the best code the JIT can produce for the equivalent Java.The typical example here is String.indexOf() and relatedAPIs, which Dalvik replaces with an inlined intrinsic. Similarly, the System.arraycopy() method is about9x faster than a hand-coded loop on a Nexus One with the JIT.

Tip: Also see JoshBloch's Effective Java, item 47.

Use Native MethodsCarefully


Developing your app with native code usingthe Android NDK isn't necessarily more efficient than programmingwith the Java language. For one thing, there's a cost associated with the Java-nativetransition, and the JIT can't optimize across these boundaries. If you'reallocating native resources (memory on the native heap, file descriptors, orwhatever), it can be significantly more difficult to arrange timely collectionof these resources. You also need to compile your code for each architectureyou wish to run on (rather than rely on it having a JIT). You may even have tocompile multiple versions for what you consider the same architecture: nativecode compiled for the ARM processor in the G1 can't take full advantage of theARM in the Nexus One, and code compiled for the ARM in the Nexus One won't runon the ARM in the G1.

Native code is primarily useful when youhave an existing native codebase that you want to port to Android, not for"speeding up" parts of your Android app written with the Javalanguage.

If you do need to use native code, youshould read our JNI Tips.

Tip: Also see JoshBloch's Effective Java, item 54.

Performance Myths


On devices without a JIT, it is true thatinvoking methods via a variable with an exact type rather than an interface isslightly more efficient. (So, for example, it was cheaper to invoke methods ona HashMap map than a Map map, even though inboth cases the map was a HashMap.) It was not thecase that this was 2x slower; the actual difference was more like 6% slower.Furthermore, the JIT makes the two effectively indistinguishable.

On devices without a JIT, caching fieldaccesses is about 20% faster than repeatedly accessing the field. With a JIT,field access costs about the same as local access, so this isn't a worthwhileoptimization unless you feel it makes your code easier to read. (This is trueof final, static, and static final fields too.)

Always Measure


Before you start optimizing, make sure youhave a problem that you need to solve. Make sure you can accurately measureyour existing performance, or you won't be able to measure the benefit of thealternatives you try.

Every claim made in this document is backedup by a benchmark. The source to these benchmarks can be found in the code.google.com "dalvik" project.

The benchmarks are built with the Calipermicrobenchmarking framework for Java. Microbenchmarks are hard to get right, soCaliper goes out of its way to do the hard work for you, and even detect somecases where you're not measuring what you think you're measuring (because, say,the VM has managed to optimize all your code away). We highly recommend you useCaliper to run your own microbenchmarks.

You may also find Traceview useful for profiling, but it's important to realizethat it currently disables the JIT, which may cause it to misattribute time tocode that the JIT may be able to win back. It's especially important aftermaking changes suggested by Traceview data to ensure that the resulting codeactually runs faster when run without Traceview.

For more help profiling and debugging yourapps, see the following documents:

·        Profiling with Traceview and dmtracedump

·        Analyzing UI Performance with Systrace

 

 


代码转载自:https://pan.quark.cn/s/8ce4326d996e 对于在 CentOS 7 系统中修改网卡配置文件后无法使设置生效的情况,经过实践验证,可以通过使用 nmcli 命令来进行调整。完成修改之后,需要重新启动虚拟机以使更改生效,这样操作流程即告完成。如果设置仍然无法生效,则表明虚拟机在启动过程中所获取的 IP 地址配置并非针对 eth0,此时可以对其它网卡的配置文件进行修改或将其移除。在 CentOS 7 系统中,网络配置的管理机制与早期版本存在差异,主要体现为采用了 Network Manager 服务来负责网络接口的管理。在某些情形下,尽管修改了 `/etc/sysconfig/network-scripts` 目录下的 `ifcfg-eth0` 文件,但网络配置却未能即时生效。此类问题的发生通常源于 CentOS 7 采用了不同于以往的配置读取方法。接下来将具体阐述如何借助 nmcli 命令来处理这一挑战。 以 root 用户身份登录系统并打开终端界面。nmcli 是 Network Manager 提供的命令行界面工具,它支持在命令行环境下执行网络连接的建立、编辑、查询及管理任务。针对修改 eth0 网卡配置的需求,可以遵循以下步骤进行操作: 1. 导航至 `/etc/sysconfig/network-scripts` 目录: ``` cd /etc/sysconfig/network-scripts ``` 2. 检查该目录内是否存在 `ifcfg-eth0.bak` 文件,该备份文件可能是先前调整配置时遗留下来的,若存在可能造成冲突。若发现该文件,可以选择将其删除: ``` [root@localhost netw...
代码转载自:https://pan.quark.cn/s/46fd08fb879c 网管教程 从入门到精通软件篇 ★一。★详尽的xp修复控制台指令及其应用!!! 放入xp(2000)的光盘,安装时选择R,执行修复! Windows XP(涵盖 Windows 2000)的控制台指令是在系统遭遇某些意外状况时的一种极具效用的诊断、检测以及恢复系统功能的工具。笔者确实一直期望能够将这方面的指令进行归纳,此次由老范辛苦整理了这份极具价值的秘籍。 Bootcfg bootcfg 命令用于启动配置与故障恢复(对大多数计算机而言,即 boot.ini 文件)。 带有特定参数的 bootcfg 命令仅在运用故障恢复控制台时方可使用。能够在命令行界面下运用带有不同参数的 bootcfg 命令。 用法: bootcfg /default 设定默认引导选项。 bootcfg /add 向引导清单中增添 Windows 安装。 bootcfg /rebuild 重复整个 Windows 安装流程并让用户选择需添加的项目。 注意:运用 bootcfg /rebuild 之前,应先借助 bootcfg /copy 命令备份 boot.ini 文件。 bootcfg /scan 探查用于 Windows 安装的全部磁盘并展示结果。 注意:这些结果被静态存储,并用于当前会话。若在当前会话期间磁盘配置发生变动,为获取更新的探查结果,必须先重启计算机,然后再次探查磁盘。 bootcfg /list 列示引导清单中已有的项目。 bootcfg /disableredirect 在启动引导程序中禁用重定向。 bootcfg /redirect [ PortBaudRrate] |[ useBio...
代码下载链接: https://pan.quark.cn/s/fc524f791b68 AA制程,即Active Alignment,被理解为主动对准,是一种用于确定零部件装配中相对位置的方法。在摄像头封装阶段,涉及图像传感器、镜座、马达、镜头、线路板等多个部件的重复组装,而传统的封装设备如CSP及COB等,均是依据设备设定的参数进行零部件的移动装配,因而零部件的叠加误差会逐渐增大,最终在摄像头上表现为拍照最清晰的位置可能偏离画面中心、四边清晰度不均等现象。伴随智能手机和其他高端电子产品的普及,摄像头模组的性能正日益受到重视。高分辨率、卓越的低光表现以及稳定视频输出是现代用户所期望的。在摄像头模组的制造环节,各部件的精准定位对成像质量具有决定性作用。因此,一种名为“AA制程”(Active Alignment)的前沿技术被开发出来,成为摄像头精密对准的核心技术。 AA制程,即Active Alignment,是一种在摄像头封装过程中应用的主动对准方法。该方法在多个组件装配阶段发挥作用,涵盖图像传感器、镜座、马达、镜头和线路板等部件。传统的封装方式,例如CSP(Chip Scale Package)和COB(Chip On Board),依赖于设备预设的参数进行组装,但随着组件数量的增加,误差也会累积,最终影响摄像头的表现。例如在成像质量上可能出现中心位置偏移、四角清晰度不一致等问题。 AA制程技术的核心在于实时监测与主动调整。在组装过程中,它借助先进的检测设备持续监控半成品的状态,并根据实时信息对组装部件进行精确修正,从而显著降低装配误差。通过这种技术,能够确保摄像头模组中各组件的相对位置准确无误,从而使得最终的成像效果更加稳定,特别是在中心区域和四角的清晰度上...
内容概要:本文介绍了一套基于Matlab实现的光子晶体90度弯曲波导的二维时域有限差分法(2D FDTD)仿真代码,旨在通过数值模拟手段深入研究光子晶体波导中的光传播特性。该资源聚焦于电磁场与光子学领域的仿真技术应用,系统实现了FDTD算法在复杂介质结构中的建模过程,涵盖空间网格剖分、时间步进迭代、完美匹配层(UPML)边界条件处理、总场散射场(TFSF)激励源设置、介电常数分布定义及电磁场演化可视化等核心模块,能够有效分析光在90度弯曲波导中的传输效率、模式分布与反射损耗等关键性能指标。; 适合人群:具备电磁场理论基础和Matlab编程能力的研究生、科研人员以及从事光子晶体器件设计与仿真的工程技术人员。; 使用场景及目标:①用于教学演示FDTD方法的基本原理与算法流程,帮助理解麦克斯韦方程的离散化求解过程;②支撑科研工作中对光子晶体弯曲波导结构的传输特性进行仿真分析与性能优化;③作为开发更复杂光子集成器件(如分束器、滤波器)数值仿真工具的基础框架; 阅读建议:建议使用者结合经典FDTD教材(如Taflove著作)深入理解算法理论,并在Matlab环境中逐模块调试代码,重点关注电场与磁场的交替更新过程、UPML吸收边界的设计实现以及TFSF源的引入方式,从而全面提升对时域电磁仿真机制的掌握与应用能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值