我正在写一个需要高效率的应用程序。这是一个不断处理浮动的应用程序。 我被告知要避免常量(静态最终字段)。 所以基本上我有一个这样的方法:
public void dealWithFloats(float x, float y)
{
...
}
因为它总是几个浮点数,所以我想知道是否应该使用数组或像
Point
这样的对象。
如果我使用数组,它基本上会是这样的:
public float[] getFloats(){
float[] array = new float[2];
float[0] = getX();
float[1] = getY();
return array;
}
我被告知要避免常量(静态最终字段)。
这是一个如此奇怪的飞越 WTF 声明。为什么不?在您的帖子中,也许出于性能原因您被告知:告诉您这件事的人希望您写:
foo(5.5);
而不是:
private static final float FOO = 5.5;
...
foo(SOME_CONSTANT);
因为第二个需要进行字段查找,速度很慢。 这是完全错误的 - 第二个片段与第一个片段一样快。运行
javap
来证明这一点 - 常量是内联的。这种关于性能如何发展的下意识想法正是编写优化代码的“不”方式。您编写“干净”的代码(干净的含义:正确抽象、易于维护、易于理解、易于测试),然后编写一个模拟预期负载的测试用例,然后运行分析器来查找热路径,并使用手头有探查器,您可以调整代码(如果您的代码编写正确,这将很容易)并重新运行探查器以查看您的攻击是否有效。
如果不按照上述方式操作,就意味着你将会失败,而且是严重的失败。你不能用“避免常量”这样的想法来优化代码。
因为它总是几个浮点数,所以我想知道是否应该使用数组或像 Point 这样的对象。A
new float[2]
和
new Point()
(其中 Point
定义为 record Point(float x, float y)
)具有相似的性能特征。如果你想要效率,那么避免这种情况并使用 2 个实际的浮点数是有道理的/可能会更有效。这个:
for (int i = 0; i < 1_000_000; i++) {
float x = 1.2;
float y = 3.4;
someMethod(x, y);
}
系统的运行比:简单得多
float[] floats = new float[2];
for (int i = 0; i < 1_000_000; i++) {
floats[0] = 1.2;
floats[1] = 3.4;
someMethod(floats);
}
因为第二个有一个间接层(堆上的对象),而第一个是全堆栈的。所以,第一个是“更快”。除此之外,JVM 非常擅长优化,并且很可能优化第二个使其同样快。这让我们回到:使用分析器和 JMH 等工具;性能调整必须有客观的数字,否则毫无意义
。 如果第二个更快,我会感到非常惊讶。这似乎不可能(但是,再次强调,
分析器,你需要所有这些东西的证据)。