-
Notifications
You must be signed in to change notification settings - Fork 1
Performance
One of the goals of perj
was to ensure the logger worked as fast as possible. This document gives a rundown on the benchmarking process.
To start with, it is worth noting that perj
is designed to be used as a building block and cross-platform out of the box. In comparison, pino is a fully mature feature rich Node.js logger. You should really check it out.
Testing the performance of perj
has been a simple process thanks to the logging benchmark being set by pino. By running benchmarks that compare perj
to pino
we can see if perj
can stand up to the tried and true standard.
If you review the primary goals of the perj
logger, you will see that Fast
is not on the top of the list. It is still a goal of this package, however not at the expense of the API or browser support. With perj
you can log any number of strings or objects in any order. This was a design decision from the start to enable rich content in log entries. Also, perj
can be used in the browser as well as it can be used in Node.js.
When logging Error
objects with perj
, the error object is serialized recursively, looking for any extra data added to the object. This was also a design decision with the knowledge that logging Error
objects would be slow compared to pino
. Keeping in mind that exceptions should be at a minimum, priority on error content trumped performance. You can change this serialization function using the serializeErrorFunction option.
It is worth noting that pino
has an advanced option being extreme mode. If you enable this option, pino
will outperform perj
. Checkout the pino
benchmarks for more detail.
To determine the performance of perj
, a benchmark file performs different logging operations. The benchmark jobs are also performed against pino
as a comparison.
For the benchmark tests, both logging packages are configured to have a similar payload when logging a simple message.
log.info('hello world')
/*
perj will log the following for the benchmark tests:
{"level":30,"pid":238226,"hostname":"dev","v":1,"time":1528345978602,"msg":"hello world","data":""}
pino will log the following for the benchmark tests:
{"level":30,"time":1526111032989,"msg":"hello world","pid":239309,"hostname":"Dev","v":1}
*/
- Lenovo Legion Pro 7i Intel Core i9-14900HX
- Node.js v22.9.0
-
perj
v4.0.0 -
pino
v9.5.0 - Date: 2024-10-17
================================================================================
perj vs pino Benchmark
================================================================================
NOTE: pino is not using extreme mode.
perj Common Log Operations x 204,700 ops/sec ±1.31% (90 runs sampled)
pino Common Log Operations x 277,287 ops/sec ±0.25% (97 runs sampled)
perj Single String Message x 3,052,397 ops/sec ±2.20% (81 runs sampled)
pino Single String Message x 2,097,915 ops/sec ±1.97% (84 runs sampled)
perj Single Long String x 52,440 ops/sec ±2.37% (89 runs sampled)
pino Single Long String x 8,638 ops/sec ±0.45% (97 runs sampled)
perj Flat Object Data x 1,609,021 ops/sec ±2.84% (85 runs sampled)
pino Flat Object Data x 1,488,158 ops/sec ±1.65% (94 runs sampled)
perj Simple Object Data x 797,010 ops/sec ±0.74% (97 runs sampled)
pino Simple Object Data x 812,983 ops/sec ±0.25% (96 runs sampled)
perj Complex Object Data x 224,077 ops/sec ±1.28% (95 runs sampled)
pino Complex Object Data x 328,022 ops/sec ±0.41% (100 runs sampled)
perj Deep Object Data x 37,589 ops/sec ±0.37% (99 runs sampled)
pino Deep Object Data x 61,721 ops/sec ±0.25% (97 runs sampled)
perj Single String And Object Data x 1,726,538 ops/sec ±2.69% (91 runs sampled)
pino Single String And Object Data x 2,058,570 ops/sec ±1.62% (92 runs sampled)
perj Logging Error Objects x 138,373 ops/sec ±0.63% (96 runs sampled)
pino Logging Error Objects x 121,419 ops/sec ±1.10% (95 runs sampled)
perj Create Single Child x 817,463 ops/sec ±0.25% (95 runs sampled)
pino Create Single Child x 1,166,109 ops/sec ±2.38% (95 runs sampled)
perj Create Two Children x 139,502 ops/sec ±0.22% (95 runs sampled)
pino Create Two Children x 106,129 ops/sec ±0.26% (98 runs sampled)
perj Create Three Children x 79,573 ops/sec ±0.25% (97 runs sampled)
pino Create Three Children x 53,808 ops/sec ±0.27% (96 runs sampled)
╔═══════════════════════════════╤════════════╤════════════╤═════════════════════╗
║ Benchmark Ops/Sec │ perj │ pino │ Result ║
╟───────────────────────────────┼────────────┼────────────┼─────────────────────╢
║ Common Log Operations │ 204699.67 │ 277287.37 │ pino: 26.18% faster ║
╟───────────────────────────────┼────────────┼────────────┼─────────────────────╢
║ Single String Message │ 3052397.05 │ 2097915.25 │ perj: 31.27% faster ║
╟───────────────────────────────┼────────────┼────────────┼─────────────────────╢
║ Single Long String │ 52440.26 │ 8638.30 │ perj: 83.53% faster ║
╟───────────────────────────────┼────────────┼────────────┼─────────────────────╢
║ Flat Object Data │ 1609021.08 │ 1488158.14 │ perj: 7.51% faster ║
╟───────────────────────────────┼────────────┼────────────┼─────────────────────╢
║ Simple Object Data │ 797010.26 │ 812982.92 │ pino: 1.96% faster ║
╟───────────────────────────────┼────────────┼────────────┼─────────────────────╢
║ Complex Object Data │ 224077.01 │ 328021.97 │ pino: 31.69% faster ║
╟───────────────────────────────┼────────────┼────────────┼─────────────────────╢
║ Deep Object Data │ 37588.52 │ 61721.49 │ pino: 39.10% faster ║
╟───────────────────────────────┼────────────┼────────────┼─────────────────────╢
║ Single String And Object Data │ 1726538.34 │ 2058570.15 │ pino: 16.13% faster ║
╟───────────────────────────────┼────────────┼────────────┼─────────────────────╢
║ Logging Error Objects │ 138372.70 │ 121419.21 │ perj: 12.25% faster ║
╟───────────────────────────────┼────────────┼────────────┼─────────────────────╢
║ Create Single Child │ 817462.78 │ 1166109.36 │ pino: 29.90% faster ║
╟───────────────────────────────┼────────────┼────────────┼─────────────────────╢
║ Create Two Children │ 139502.33 │ 106129.32 │ perj: 23.92% faster ║
╟───────────────────────────────┼────────────┼────────────┼─────────────────────╢
║ Create Three Children │ 79572.90 │ 53808.27 │ perj: 32.38% faster ║
╚═══════════════════════════════╧════════════╧════════════╧═════════════════════╝
If you would like to try out the benchmark yourself, follow these steps:
- Clone the
perj
repository:
git clone https://github.com/grantcarthew/node-perj
- Change directory into
node-perj
and install the package dependencies:
npm install
- The
pino
logger is not a dependency of theperj
package. You will need to installpino
:
npm install pino --no-save
.
- Run the benchmark:
npm run benchmark
.