在我提出问题之前,能否请您不要对无缘由的优化进行演讲。以下问题仅为学术性质。
我一直在思考Java中根(即经常使用且经常彼此访问)类之间访问的效率问题,但这适用于大多数面向对象语言/编译器。我猜想最快的方式是使用static final引用来访问Java中的某些内容。理论上,由于该引用在加载时可用,因此一个好的JIT编译器将消除任何引用查找以访问变量,并将任何访问指向该变量的恒定地址。也许出于安全原因,它并不起作用,但请听我说...
假设我已经决定存在一些操作顺序问题或一些必须在启动时传递的参数,这意味着即使我费心让每个类构造另一个类(建议Java类对彼此具有静态final引用),我也不能拥有静态final引用。我可能不想这样做的另一个原因是...哦,例如,我正在为某些这些类的平台特定实现提供支持。;-)
现在我只剩下两个明显的选择。我可以让我的类通过静态引用(在某个系统中央类上)了解彼此,在构造完所有类之后设置该引用(在此期间,我规定它们不能相互访问,从而至少在构造期间消除操作顺序问题)。另一方面,如果我现在决定解决操作顺序问题或将其交由传递参数的人负责,或更重要的是为这些想要相互引用的类提供平台特定实现,那么这些类可以具有实例最终引用。
静态变量意味着您不必查找变量所属类的位置,从而节省了一个操作。最终变量意味着您根本不必查找值,但它必须属于您的类,因此您可以节省“一个操作”。好吧,我知道我现在有点牵强附会!
然后我想到了其他事情:我可以使用static final存根类,类似于奇怪的接口,其中每个调用都被委派给一个“impl”,该“impl”只能扩展存根。然后可能需要进行双重函数调用来运行功能,并且我猜您可能不能再声明方法为final。我假设如果适当声明,则它们可能会被内联,然后放弃,因为我意识到我现在必须考虑是否可以使对“impl”的引用成为静态的,最终的,或...
那么这三者中哪个会最快呢?:-)
还有其他降低频繁访问开销的想法或向JIT编译器提示性能的其他方法吗?
更新:在运行各种测试并阅读http://www.ibm.com/developerworks/java/library/j-jtp02225.html之后,我发现大多数调优时通常会看的东西,例如C ++,与JIT编译器完全无关。我曾经看到它一次、两次地运行30秒的计算,但第三次(以及随后的运行)决定“嘿,你没有读取那个计算的结果,所以我不运行它!”。
顺便说一下,您可以测试数据结构,我能够使用微基准测试开发出更适合我的需要的arraylist实现。访问模式必须足够随机,以使编译器猜测,但它仍然可以通过我的更简单和更调整的代码更好地实现一个泛型化的增长数组。
就这里的测试而言,我根本无法获得基准测试结果!从一个终极 vs 非终极对象引用调用函数并读取变量的简单测试揭示了比JVM的访问模式更多的JIT信息。难以置信的是,在方法中的不同位置调用相同的函数和相同的对象会使花费的时间因四倍而异!
正如IBM文章中的人所说,测试优化的唯一方法是在现场测试。
感谢所有指引我的人。
我一直在思考Java中根(即经常使用且经常彼此访问)类之间访问的效率问题,但这适用于大多数面向对象语言/编译器。我猜想最快的方式是使用static final引用来访问Java中的某些内容。理论上,由于该引用在加载时可用,因此一个好的JIT编译器将消除任何引用查找以访问变量,并将任何访问指向该变量的恒定地址。也许出于安全原因,它并不起作用,但请听我说...
假设我已经决定存在一些操作顺序问题或一些必须在启动时传递的参数,这意味着即使我费心让每个类构造另一个类(建议Java类对彼此具有静态final引用),我也不能拥有静态final引用。我可能不想这样做的另一个原因是...哦,例如,我正在为某些这些类的平台特定实现提供支持。;-)
现在我只剩下两个明显的选择。我可以让我的类通过静态引用(在某个系统中央类上)了解彼此,在构造完所有类之后设置该引用(在此期间,我规定它们不能相互访问,从而至少在构造期间消除操作顺序问题)。另一方面,如果我现在决定解决操作顺序问题或将其交由传递参数的人负责,或更重要的是为这些想要相互引用的类提供平台特定实现,那么这些类可以具有实例最终引用。
静态变量意味着您不必查找变量所属类的位置,从而节省了一个操作。最终变量意味着您根本不必查找值,但它必须属于您的类,因此您可以节省“一个操作”。好吧,我知道我现在有点牵强附会!
然后我想到了其他事情:我可以使用static final存根类,类似于奇怪的接口,其中每个调用都被委派给一个“impl”,该“impl”只能扩展存根。然后可能需要进行双重函数调用来运行功能,并且我猜您可能不能再声明方法为final。我假设如果适当声明,则它们可能会被内联,然后放弃,因为我意识到我现在必须考虑是否可以使对“impl”的引用成为静态的,最终的,或...
那么这三者中哪个会最快呢?:-)
还有其他降低频繁访问开销的想法或向JIT编译器提示性能的其他方法吗?
更新:在运行各种测试并阅读http://www.ibm.com/developerworks/java/library/j-jtp02225.html之后,我发现大多数调优时通常会看的东西,例如C ++,与JIT编译器完全无关。我曾经看到它一次、两次地运行30秒的计算,但第三次(以及随后的运行)决定“嘿,你没有读取那个计算的结果,所以我不运行它!”。
顺便说一下,您可以测试数据结构,我能够使用微基准测试开发出更适合我的需要的arraylist实现。访问模式必须足够随机,以使编译器猜测,但它仍然可以通过我的更简单和更调整的代码更好地实现一个泛型化的增长数组。
就这里的测试而言,我根本无法获得基准测试结果!从一个终极 vs 非终极对象引用调用函数并读取变量的简单测试揭示了比JVM的访问模式更多的JIT信息。难以置信的是,在方法中的不同位置调用相同的函数和相同的对象会使花费的时间因四倍而异!
正如IBM文章中的人所说,测试优化的唯一方法是在现场测试。
感谢所有指引我的人。