-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve performance when logging is disabled #23893
Conversation
Should provide a decent performance boost:
code// https://github.com/tinylibs/tinybench
import {Bench, hrtimeNow} from 'tinybench';
import logger from './logger.js';
import loggernew from './loggernew.js';
const bench = new Bench({time: 5000, warmupTime: 1000, now: hrtimeNow});
logger.init(); // set to 'info' with silenced Console transport
loggernew.init(); // set to 'info' with silenced Console transport
bench.add('plain log', function() {
logger.error('test');
});
bench.add('plain log new', function() {
loggernew.error('test');
});
bench.add('stringify log', function() {
logger.error(`test ${JSON.stringify({ a: 1, b: 2 })}`);
});
bench.add('stringify log new', function() {
loggernew.error(() => `test ${JSON.stringify({ a: 1, b: 2 })}`);
});
bench.add('plain log - disabled', function() {
logger.debug('test');
});
bench.add('plain log new - disabled', function() {
loggernew.debug('test');
});
bench.add('stringify log - disabled', function() {
logger.debug(`test ${JSON.stringify({ a: 1, b: 2 })}`);
});
bench.add('stringify log new - disabled', function() {
loggernew.debug(() => `test ${JSON.stringify({ a: 1, b: 2 })}`);
});
await bench.warmup(); // make results more reliable, ref: https://github.com/tinylibs/tinybench/pull/50
await bench.run();
console.table(bench.table());
await logger.end();
await loggernew.end(); PS: Should remove package json edits, same in ZH PR. |
Thanks @Nerivec !! Great feedback. Specially loved your perf test. I created one as well but it was so ugly I didn't thought about quoting it here. This is my first ts/js coding so I have lot to learn from your comments. I will work on fixes tomorrow. Thanks again for spending time on this. |
I submitted all changes. Thanks again for the CR! |
z2m uses |
await controller.start(); | ||
logger.debug.mockClear(); | ||
await MQTT.events.message('zigbee2mqtt/skip-this-topic', 'skipped'); | ||
expect(logger.debug).toHaveBeenCalledWith("Received MQTT message on 'zigbee2mqtt/skip-this-topic' with data 'skipped'", LOG_MQTT_NS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of having to do this can't we modify stub/logger.js
to evaluate the lambda?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See https://github.com/Koenkk/zigbee2mqtt/pull/23893/files#r1750650326 I was thinking, ignoring the logging completely and spying on eventBus instead? Cleaner to test the code than the logs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this specific test case it's possible, but there are also some test cases on which this cannot be used. So having the stub/logger.js
modified would be nice anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did both:
- Changed the code to spy on eventBus as it really seems more robust.
- Changed the stub logger implementation so it will be easy to spy on the actual logger message. I added an example of this in the last line of the 'Handle mqtt message' test case so you can see that it is simple to do.
I saw that usage only as part of |
I think I resolved all your comments. Let me know if anything else is needed. Thanks guys!! |
Quick regex search (might be others):
Lines 114 to 119 in 403d3c0
zigbee2mqtt/lib/extension/receive.ts Lines 111 to 114 in 403d3c0
Also these, though minimal impact since only called once on start (but removes potential requests to the adapter, which is always good): Lines 58 to 59 in 403d3c0
Lines 125 to 126 in 403d3c0
|
I found couple more usages I could swap. I think the commit is ready to merge. Thanks for your support. |
This reverts commit b409d53.
Fix prettier issue
OK, now it is really ready. Sorry for the mess. |
Thanks @tomer-w ! |
Thank you!! Amazing project which is centerpiece for home automation. |
Improve the logging performance by not running expensive JSON.stringify when the logging is disabled.
The old pattern was something like that:
This was calling the
stringify
function even if eventually the logger was disabled.The new pattern is:
Which will not call the lambda if the tracing is disabled.
The logger function will accept both string messages as they used to be and the new lambda format, so there is no need to change all logging calls, only the ones that are deemed expensive.
I am also adding
Logger.isEnabled
function which can be used by the caller to decide if there is a need to prepare complex log message.I also changed all the expensive calls to the logger in the zigbee-herdsman to use the new functionality:
Koenkk/zigbee-herdsman#1178