probe.gl — Benchmarking in Node.js
Looking for benchmarking in Node.js? Let me introduce probe.gl —A collection of JavaScript front-end debugging tools made by Uber.
probe.gl is a collection of JavaScript front-end debugging tools made by Uber. probe.gl has a variety of tools but today we will focus on Bench
, a benchmarking harness class that makes it easy to create "micro-benchmarks" for optimization and regression testing purposes. In this story we’ll be building a sample React application that implements the probe.gl benchmarking rig. If you want to find more documentation on probe.gl, you can go here.
Note: You can see the output of the benchmarks at the bottom of this story.
Before we start
Before we start, I want to note that all the code in this story can be found on GitHub here: probegl-benchmarking-sample. Feel free to use it in your own personal and professional projects and change it to fit your needs.
Setup
To start things off let’s create a new React project
Note: I am using Node version v18.12.0
npx create-react-app benchmark-react-app
cd benchmark-react-app
Next, we will need to add probe.gl bench
to our project
npm install "@probe.gl/bench"
Sample Functions
Next, let’s get the sample functions out of the way. Navigate to App.js and create the two sample functions we’ll be benchmarking: sample_function_sleep_async and sample_function_math_sqrt. The first function sleeps for 100 milliseconds. The second function just calls the built-in Math.sqrt function.
Prerequisite
Before we write our benchmarks, we need to complete some prerequisites. In this case, we need to create a probe.gl helper file called ProbeGLHelper.js. At first glance, this file contains a lot of code, and you’re right. However, I go into great detail line by line describing all that this file contains further down below.
There’s a lot to unpack. This helper file contains two main functions: customLogger
and runBenchmarks
. customLogger
is used for logging our benchmark results. runBenchmarks
is used to run our benchmarks with more control. Let’s go through ProbeGLHelper.js line by line.
Line 1–7: These are helper variables used in both helper functions
Lines 9–40: These functions format the customLogger
output for readability purposes
Line 47: This line gathers all the variables probe.gl returns from a benchmarking test
Lines 49: Every time probe.gl runs a benchmark customLogger
gets called and this switch statement is triggered
Line 59: On this line we store the Coefficient of Variation returned from probe.gl and store it in an array called cv. We use this array in our final result table on line 78
Lines 61–90: This section is called when probe.gl completes all the benchmark tests. This is where customLogger
builds a table that is displayed to the console
Note: You can adjust the output of your benchmark results in lines 71–86
Lines 95–112: This section offers us more control over probe.gl when running benchmarks. For example, Lines 96–102 allow you to change the number of async tests run per iteration (By default 10 async tests would run per iteration. Here we changed that to 1 async test run per iteration)
Create Benchmarks
Before we write our benchmarks, we need to add the following import statements to the top of App.js
import React, { useEffect } from 'react';
import { Bench } from '@probe.gl/bench';
import { customLogger, runBenchmarks } from './ProbeGLHelper';
Finally, we’re ready to write some benchmarks! Let’s start by creating an async function called sample_benchmark. I go into great detail line by line describing all that this function contains further down below.
More to unpack. This function creates our benchmarks! Let’s go through sample_benchmark line by line.
Lines 2–6: This is where we set options for Bench
, including our customLogger
Line 7: Initialize the probe.gl benchmarking harness class, Bench
, passing benchOptions
as the parameter
Line 10 (Same concept for line 18): Create a group that will contain specified benchmarks
Lines 11–15 (Same concept for lines 19–23): Here we give our benchmark test a priority (optional)
, an id
, a function
that we are going to test, and an initFunction
(this is deprecated so we pass null)
Note: The function signatures for add/addAsync are:
add(priority, id, testFunc, initFunc[Deprecated]) : Bench
addAsync(priority, id, testFunc, initFunc[Deprecated]) : Bench
Line 26: Pass bench
to our helper function runBenchmarks
that we created in our helper file. This will run the benchmarks we’ve created.
Run Benchmarks
Now in the function App replace all the default generated code with the code below.
To start our application run the following command
npm run start
When you open your web browser console, you should see something similar to the screenshot below (if you don’t, refresh the page. The browser sometimes skips console logs on first page load)
You’ve successfully implemented benchmarking in Node.js using probe.gl. If you have questions or want to see a specific benchmarking scenario using probe.gl, let me know!
Feel free to leave a response if you run into any issues or something is unclear. Happy Coding and God Bless!