Performance comparison if / else vs state change vs noop in HTMLCanvasElement render loop

31 views Asked by At

In a project related to HTMLCanvasElement, I have a base class Object2d which stores object's state with many options, e.g. rotation, debug, etc., that affect the rendering phase.

A typical render function for the instances of this class would be:

public render() : void {

  const ctx: CanvasRenderingContext2D = this._canvas.getContext('2d);

  if (this.rotation !== 0) {
    ctx.rotate(this.rotation);
  } 
    
  this._drawObject(ctx);
    
  if (this.debug) {
    this._renderDebug(ctx);
  }
    
  if (this.rotation !== 0) {
    ctx.rotate(-this.rotation);
  }

}

Another way, would pass by changing the context state even if rotation is 0 (but the if remains with debug in this example):

public render() : void {

  const ctx: CanvasRenderingContext2D = this._canvas.getContext('2d);

  ctx.rotate(this.rotation);
    
  this._drawObject(ctx);
    
  if (this.debug) {
    this._renderDebug(ctx);
  }
    
  ctx.rotate(-this.rotation);

}

I choosed (and I may be wrong!) to switch functions according to the value of - in this case - rotation and debug:

private _beginRotation = noop; // 'noop' is a function that does nothing.
private _endRotation = noop;
private _renderDebug = noop;

// Happens only when changing rotation value.
public set rotation(value: number) {

  this._rotation = value;

  if (this._rotation !== 0) {

    // Will rotate the context.
    this._beginRotation = this.myBeginRotationActualMethod;

    // Will restore the context rotation.
    this._endRotation = this.myEndRotationActualMethod;
  
  } else {

    this._beginRotation = noop;
    this._endRotation = noop;

  }

}

// Happens only when changing 'debug' value.
public set debug(value: boolean) {

  this._debug = value;

  if (this._debug) {
    this._renderDebug = this.myDebugActualMethod;
  } else {
    this._renderDebug = noop;
  }

}

public render() : void {

  const ctx: CanvasRenderingContext2D = this._canvas.getContext('2d);

  this._beginRotation(); // Calls noop or the actual context rotation function.

  this._drawObject(ctx);

  this._renderDebug();

  this._endRotation(); // Again: noop, or the actual context restore function.

}

My questions are:

  • Is calling an empty function faster than passing by a if condition?
  • Is changing the state, i.e. by calling ctx.rotate even with 0 value, faster than passing by the noop function or the if statement?
0

There are 0 answers