Java 安卓系统性能-';避免内部getter/setter';
只需在开发人员网站上阅读以下内容: 在C++等本地语言中,使用GETTER(例如,I= GETCONTUTE())代替直接访问字段(I= MCOUNT)是常见的做法。对于C++来说,这是一个很好的习惯,因为编译器通常可以内联访问,如果需要限制或调试字段访问,则可以随时添加代码。 在Android上,这是个坏主意。虚拟方法调用的开销比实例字段查找要大得多。遵循常见的面向对象编程实践并在公共接口中使用getter和setter是合理的,但是在类中,您应该始终直接访问字段 如果没有JIT,直接字段访问比调用一个微不足道的getter快3倍左右。使用JIT(直接字段访问和访问本地字段一样便宜),直接字段访问比调用一个微不足道的getter快7倍左右。这在Froyo中是正确的,但在将来JIT内联getter方法时会有所改进 2019/05更新:在当前版本中,上述材料已从文档中删除 那么,是说您将在类中使用字段访问:Java 安卓系统性能-';避免内部getter/setter';,java,android,performance,optimization,Java,Android,Performance,Optimization,只需在开发人员网站上阅读以下内容: 在C++等本地语言中,使用GETTER(例如,I= GETCONTUTE())代替直接访问字段(I= MCOUNT)是常见的做法。对于C++来说,这是一个很好的习惯,因为编译器通常可以内联访问,如果需要限制或调试字段访问,则可以随时添加代码。 在Android上,这是个坏主意。虚拟方法调用的开销比实例字段查找要大得多。遵循常见的面向对象编程实践并在公共接口中使用getter和setter是合理的,但是在类中,您应该始终直接访问字段 如果没有JIT,直接字段访
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
}
}
尽管
b.innerObject
速度更快,但随着技术的进步(更好的CPU、JIT等),这两个选项之间的差异变得更小
唯一重要的一点是,在始终执行的密集循环中执行时。例如,在游戏的
onDraw
方法中,当你在数百个对象中循环时 请记住,只有当相关成员每秒被访问数千次时,这些性能考虑才是相关的
直接访问可能是一个好主意的一个很好的例子是游戏的场景图()
使用内部getter和setter对性能的影响也适用于外部getter和setter 然而,在外部情况下,接受者和接受者在其他领域有显著的优势;e、 保留封装,减少有害耦合,使代码更易于维护,等等。因此,使用getter和setter通常被认为是最佳实践,尽管这可能会导致性能下降 性能下降是旧版Android JIT编译器局限性的结果。姜饼显著改善了这种情况(见-…并注意是谁写的答案!),并且继续改善。事实上,在当前(2019)版本的中,关于内部getter和setter的整个建议部分已经删除
一般来说,为劣质平台“调优”代码是一个坏主意,特别是如果有一个合理的机会,一个更好的平台即将出现 由于getter和setter是函数调用,因此它们总是有开销。当您在同一个对象中时,您可以通过不使用它们来优化代码,因为您知道它们的用途,并且不需要从它自己的对象中抽象/封装它们 我认为你也需要从不同的角度来看待它:
您确实需要在percase基础上进行优化,如果我正在构建两个模块,其中一些组件只能由彼此访问,我可能会创建一个静态字段,否则我将坚持使用getter/setters性能方面,访问
this.field
或this.field
没有区别
实例字段更容易被承载它的对象访问的感觉只是一种语法错觉
哦,说真的,Android应用程序会变得多复杂?许多OO咒语来自于构建怪物应用程序。如果你的小应用程序使用像structs这样的对象,有什么大不了的
即使在一个巨大的应用程序中,只要它在内部,并且访问某个字段的所有源代码都可用于重构,那么公开字段就没有任何问题 请注意,setter和getter(在Java中)的另一个问题是它们使用起来很麻烦 假设在下一个练习中,我们需要在对象的字段中修改字段 在java中是:
object.getField().getSubField().setField3("hello"); // ugly
而在C#中,相同的代码是(即使使用封装)
因此,在Java(或android)中使用公共字段要干净得多:
object.field.subfield.field3="hello"; // fine too
要指出这一点,请记住Dalvik不是JVM,这种做法不应该被视为普通Java开发中的一般做法?遵循常见的面向对象编程实践并在公共接口中使用getter和setter是合理的。另外:不要过度设计。只要使用getter,除非你做了大量的调用。或者速度有问题。等等,android JIT不内联琐碎的函数调用?我的意思是,这是任何JIT的基本优化之一-确保它必须确保类没有被覆盖等等,但这是99/100 easy中的一个。很难相信。@Voo-商业原因可能使得现在就有必要交付二流产品,而不是等待6个月直到它成为一流产品。Java和Javascript(以及Windows Vista和…)也发生了同样的事情。如果你忽略历史,这只是“很难相信”而已。“getter和setter总是有开销,因为它们是函数调用”在任何现代的JIT-in热点上都是不正确的,除非在一些罕见的情况下是内联的(即setter实际上在子类中被覆盖,jit不能保证对象的身份之一——或者说,几乎从来没有)啊,但这是TrainCrank反模式,只与最近的邻居交谈并获取代码<
object.getField().getSubField().setField3("hello"); // ugly
object.Field.SubField.Field3="hello"; // fine
object.field.subfield.field3="hello"; // fine too