编写Java程序时,对CPU如何利用其缓存存储数据有影响吗?例如,如果我有一个经常访问的数组,那么它是否足够小以适合一个高速缓存行(在64位计算机上通常为128字节)是否有帮助?如果我将一个经常使用的对象保持在该限制之内,我可以期望它的成员使用的内存紧密并留在缓存中吗?
背景:我正在构建一个压缩的数字树,它受C语言中Judy数组的启发很大。虽然我主要追求其节点压缩技术,但Judy将CPU缓存优化作为主要设计目标,并将节点类型设置为以及在它们之间切换的启发式方法在很大程度上受到影响。我想知道我是否也有机会获得这些好处?
编辑 : 到目前为止,答案的一般建议是,当您离Java如此之远时,不要尝试对计算机级别的细节进行微优化。
我完全同意,因此我不得不(希望)添加一些澄清的评论,以更好地解释为什么我认为这个问题仍然有意义。这些如下:
由于计算机的构建方式,有些事情通常使计算机更容易处理。我已经看到Java代码在压缩数据(来自内存)上的运行速度明显加快,即使解压缩必须使用其他CPU周期也是如此。如果将数据存储在磁盘上,很明显为什么会这样,但是当然在RAM中是相同的原理。
现在,计算机科学对于这些东西是什么有很多话要说,例如,C语言中的引用位置很棒,而我想它在Java中仍然很棒,如果它有助于优化运行时来执行更多聪明的事情,则可能更多。但是您如何实现它可能会大不相同。在C语言中,我可能会编写代码来管理更大的内存本身,并使用相邻的指针存储相关数据。
在Java中,我不能(也不想)对特定的运行时如何管理内存了解得太多。因此,我也必须将优化提高到更高的抽象水平。我的问题基本上是,我该怎么做?对于引用的局部性,在Java中我正在研究的抽象级别上,“紧密结合”是什么意思?同一个对象?同类型?相同的数组?
一般来说,从隐喻上来讲,我不认为抽象层会改变“物理定律”。即使您不再调用malloc()
,每次用完空间时将数组的大小加倍也是一个不错的策略。
Java取得良好性能的关键是编写惯用的代码,而不是试图超越JIT编译器。如果您编写代码以尝试以某种方式影响其在本机指令级别上执行操作,则您更有可能朝自己开枪。
这并不是说像参考地这样的通用原则并不重要。它们可以,但是我认为使用数组等是性能感知的惯用代码,而不是“棘手的”。
HotSpot和其他优化运行时 非常
聪明如何针对特定处理器优化代码。(例如,查看此讨论。)如果我是专家的机器语言程序员,我会写机器语言,而不是Java。如果不是,那么认为我可以比专家做得更好来优化代码,这是不明智的。
同样,即使您确实知道为特定CPU实现某些功能的最佳方法,Java的优点还是可以在任何地方写入一次即可运行。“优化”
Java代码的巧妙技巧往往会使JIT难以识别优化机会。遵循常见习惯用法的直截了当的代码对于优化器来说更容易识别。因此,即使您获得了适用于测试平台的最佳Java代码,该代码也可能在不同的体系结构上可怕地执行,或者充其量只能在未来的JIT中无法利用增强功能。
如果您想要良好的性能,请保持简单。 真正 聪明的团队正在努力使其快速发展。
问题内容: 我是Java新手。根据我的理解: 我们无法实例化。我们只能实例化实现的。 所述关键字被用来创建从类的对象。 但是,当我阅读某些Java程序的源代码时,我发现有时会实例化一个Interface。例如: 范例1: 范例2: 在上面的示例中,ActionListener和Runnable都是Java接口。我可以知道为什么可以在这些代码中实例化它们吗? 实例化接口的目的是什么?参考此示例,似乎
如果接口只是一个标记接口,用于在 java 中传递有关类的某种元数据 - 我有点困惑: 在阅读了java的序列化算法(元数据从下到上,然后从上到下的实际实例数据)的过程之后,我无法真正理解哪些数据不能通过该算法进行处理。 简而言之: 哪些数据可能导致? 我怎么知道我不应该为我的类添加子句?
问题内容: 运行此命令时: 响应为: 这对我来说真是太棒了。我本以为这会带来编译时错误。 为什么我可以在Java中抛出null,为什么将其转换为NullPointerException? (实际上,鉴于我抛出的是null,因此我不知道这是否是“ upcast”) 除了一个非常愚蠢的面试问题(请没人在面试中问这个问题)之外,我看不到任何理由。也许您想被解雇,但这就是…我的意思是,为什么还会有人呢?
项目的数据库连接我是用HikariCP,单个增删查改速度是还算快的。但请求一多,速度就变得很慢很慢了。请问这个可以怎么优化? 然后我是这么配置的
问题内容: 我试图进行搜索并弄清楚它是如何工作的,但是我很难找到一个解释。 如果我的变量类型为() 怎么办?我知道接口可以代表很多事情,但是他在这里发生的事情的高层概述是什么? 问题答案: 这是一个类型断言: 类型断言提供对接口值的基础具体值的访问。 https://tour.golang.org/methods/15 如果该断言不成立,则会引发恐慌。要测试该值是否为特定类型T,可以使用以下命令:
问题内容: 在Python中,用于初始化不可变类型,通常用于初始化可变类型。如果将其从语言中删除,该怎么办(轻松)? 例如, 可以这样重写: 为澄清问题的范围:这不是一个问题关于如何以及是使用或它们之间有什么区别。这是一个问题,如果从语言中删除将会发生什么。有什么坏事吗?事情会变得很难或不可能吗? 问题答案: 您可以在中进行的所有操作都可以在中完成。 那么,为什么要使用? 因为您不必将实例存储在变