OpenGL 渲染器循环中哪个更有效率:"if" 运算符或 lambda?

What is more productive in the OpenGL renderer loop: "if" operator or lambda?

开始渲染游戏时,部分算法发生变化(处理屏幕上的点击)。

有两种选择。 1.使用"if"运算符:

public class Leve1 implements GLSurfaceView.Renderer {
  private boolean isLoadGame = false;
  public void onSurfaceChanged(GL10 glUnused, int width, int height) {
    ...
    isLoadGame = true; // game is now loaded
  }
  // this method is called often in the render loop
  public void setPassXY(float x, float y) {
    if (isLoadGame) {
      ... // perform algorithm 
    }
  }
}

2。使用 lambda(没有 "if"):

public class Leve1 implements GLSurfaceView.Renderer {
  // when the game is not loaded yet use the empty method body
  private PressXYInterface<Float, Float> pressXY = (pressX, pressY) -> {};
  public void onSurfaceChanged(GL10 glUnused, int width, int height) {
    ...
    pressXY = (passX, passY) -> { 
      ... // game is now loaded - add algorithm
    };
  }
  // this method is called often in the render loop
  public void setPassXY(float x, float y) {
    pressXY.invoke(x, y); // perform algorithm
  }
}

@FunctionalInterface
public interface PressXYInterface<T, U> {
  void invoke(T x, U y);
}

问题:在性能方面使用哪种方法更好?

TL;DR - 没有一个正确答案。这取决于很多因素。对您的 真实 应用程序进行基准测试是获得可靠答案的唯一途径。


以下是一些问题:

一方面,使用 lambdas 的版本节省了 if 语句。

另一方面,使用方法调用的版本可能会被 JIT 编译器内联。 (这些 lambda 调用无法内联,因为在不同的时间点调用站点可能调用不同的 lambda。)

另一方面,如果// perform algorithm足够复杂,它会太大而无法内联。

另一方面,如果 algorithm 太大而无法内联,也许 if 测试的成本将微不足道。

另一方面,if 测试可能比您想象的要便宜。例如:

  • 如果代码在切换到 isLoadGame == true 状态后进行了 JIT 编译,那么统计信息可能会告诉 JIT 编译器针对测试成功的情况进行优化。
  • (硬件)分支预测可能会根据该测试的模态行为进行调整。

另一方面,我不清楚哪些版本需要进行简单调用或虚拟调用。或者 JIT 编译器 是否可以 优化虚拟调用。我根本不知道。 (检查字节码会给出部分答案。)

然后就是JIT编译器版本不同,硬件ISA不同,硬件实现不同的问题

简而言之,预测哪种方法在现实中表现更好的因素太多了。

这也意味着微基准测试不太可能有帮助。上述许多因素将严重取决于实际应用程序代码和应用程​​序启动的方式。您将需要对实际应用程序进行基准测试以获得有意义的结果。