Android性能 – “避免内部获取者/设置者”

只要在开发者网站上阅读:

避免内部获得者/设置者

在像C ++这样的本地语言中,通常使用getter(例如i = getCount())而不是直接访问字段(i = mCount)。 对于C ++来说,这是一个很好的习惯,因为编译器通常可以内联访问,如果需要限制或debugging字段访问,则可以随时添加代码。

在Android上,这是一个坏主意。 虚拟方法调用比实例字段查找更昂贵。 遵循通用的面向对象的编程实践是合理的,并且在公共接口中有getter和setter,但是在一个类中你总是应该直接访问字段。

没有JIT,直接字段访问比调用一个简单的getter快3倍。 使用JIT(直接字段访问与访问本地一样便宜),直接字段访问比调用一个简单的getter快7倍。 这在Froyo中是正确的,但是当JIT使用getter方法的时候将会有所改进。

所以它是说你会在类中使用字段访问:

public class MyObject { public Object innerObject; // This would be private if I was using a getter public void doSomeStuff(){ if(innerObject){ // Within class access like this // .... } } public Object getInnerObject(){ // This would be removed if I was using field access return innerObject; } } 

但是从另一个对象访问呢?

  public class SecondObject { public void doSecondSomething(){ MyObject ob = new MyObject(); Object inner; //This is my question basically (from an Android performance perspective) inner = ob.getInnerObject(); // OR inner = b.innerObject } } 

Solutions Collecting From Web of "Android性能 – “避免内部获取者/设置者”"

使用内部getter和setter的性能打击也适用于外部getter和setter。

然而,在外部情况下,吸毒者和安装者在其他方面有显着的好处; 例如保存封装,减less有害耦合,使代码更易于维护等等。 所以,尽pipe可能会出现性能问题,但通常被认为是使用getter和setter的最佳实践

性能受到当前一代 Android JIT编译器的限制。 这种情况肯定会改善与姜饼的改善。 (参考 – https://stackoverflow.com/a/4930538/139985 …并注意谁写的答案!)

一般来说,将代码“调整”到劣质平台是一个糟糕的主意,特别是如果有合理的可能,更好的代码正在进行中。

尽pipeb.innerObject速度更快,但随着技术的进步(更好的cpus,JIT等),两种select之间的差异会变小。

唯一的问题是在密集的循环中执行,而这些循环会一直执行。 例如,在游戏的onDraw方法中,当循环通过数百个对象时。

请记住,只有在每秒访问成员数千次的情况下,这些性能考虑才是相关的。

直接访问可能是一个好主意的一个很好的例子是游戏的场景图( libgdx )

 public abstract class Actor { public Group parent; public final String name; public boolean touchable = true; public float x; public float y; public float width; public float height; public float originX; public float originY; public float scaleX = 1; public float scaleY = 1; public float rotation; public final Color color = new Color(1, 1, 1, 1); 
 // this is faster inner = b.innerObject // but this won't hurt performance much because // it's assumed that it will be rare inner = ob.getInnerObject(); 

Getters和Setter总是有开销,因为它们是函数调用。 当你在同一个对象中时,你可以通过不使用它们来优化你的代码,因为你知道它们用于什么,而不需要从它自己的对象中抽象/封装它们。

我认为你也需要从另一个angular度来看待它:

  1. 没有getter / setter会打破普通的oops做法吗? 如果您制作其他人将使用的对象/模块,则不需要直接引用。

  2. 你真的不想在最后使用getters / setter,除非sh!*优化出来的函数调用会有开销。

你真的需要在percase的基础上进行优化,如果我正在构build两个模块,其中一些组件只能相互访问,我可以做一个静态的领域,否则我会坚持getters / setters

性能方面,访问this.fieldthat.field没有区别。

实例字段更容易被托pipe对象访问的感觉仅仅是语法错觉。

OO明智,认真,Android应用程序有多复杂? 许多OO的咒语都来自构build怪物应用程序。 如果你的小应用程序使用结构体这样的对象,那有什么大不了的?

即使在一个巨大的应用程序中,只要它在内部,并且访问一个字段的所有源代码都可用于重构,那么暴露这些字段都是没有问题的。

为了logging,setter和getter(Java)的另一个问题是它们使用起来很难受。

假设下一个练习,我们需要修改一个对象字段的内部字段

在java中是:

  object.getField().getSubField().setField3("hello"); // ugly 

而在C#中相同的代码是(即使封装)

  object.Field.SubField.Field3="hello"; // fine 

所以,在Java(或Android)中使用公共领域是一个更清洁:

  object.field.subfield.field3="hello"; // fine too