Skip to content
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

Update Onyx.printMetrics format #89

Merged
merged 7 commits into from
Jul 16, 2021

Conversation

kidroca
Copy link
Contributor

@kidroca kidroca commented Jul 16, 2021

@marcaaron

Details

This PR does not change how Onyx work and only affects dev, debug, benchmark usages
The changes here update the print format so that a summary table is printed
This table can be easily selected and pasted in xls

Sample Output

Screenshot 2021-07-16 at 2 57 28

Related Issues

Expensify/App#2667

Automated Tests

Covered by existing tests

Linked PRs

kidroca added 5 commits July 14, 2021 14:32
This doesn't represent accurate or useful information
It was just the total time divided by the count
of decorated methods
For example copying the raw data to excel
allow for easier formatting sorting and
other math operations
@kidroca kidroca requested a review from a team as a code owner July 16, 2021 00:00
@MelvinBot MelvinBot requested review from joelbettner and removed request for a team July 16, 2021 00:01
lib/decorateWithMetrics.js Show resolved Hide resolved
lib/decorateWithMetrics.js Show resolved Hide resolved
Copy link
Contributor

@marcaaron marcaaron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. But I am hoping we can maybe clear up what last means. Probably just needs a small language tweak here and there to make things more obvious for the next ones to use this tool.

lib/decorateWithMetrics.js Show resolved Hide resolved
lib/decorateWithMetrics.js Show resolved Hide resolved
lib/decorateWithMetrics.js Show resolved Hide resolved
lib/decorateWithMetrics.js Outdated Show resolved Hide resolved
kidroca added 2 commits July 16, 2021 12:49
This does not happen while debugging with Chrome, which is what I used
for the most of the time and never noticed the issue

Since the update for Reanimated 2 (TurboModules/JSI)
It's no longer possible to use the old (Chrome) debugging flow
I've discovered the timing information was not at all relative to
app launch, the duration between start/end is correct but the
start/end values are otherwise useless if they display like 8468.7min
To be useful they need to be relative to app launch time

Since timing otherwise works correct, we can capture an offset - APP_LAUNCH_TIME
and subtract this value from the timings we make to capture a correct
start/end time relative to APP_LAUNCH_TIME
Comment on lines +9 to +12
/* For some reason `performance.now()` does not start from `0` but a very large offset
* like `508,080,000` see: https://github.com/facebook/react-native/issues/30069
* Capturing an offset allows us to record start/ends times relative to app launch time */
const APP_LAUNCH_TIME = performance.now();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've found this issue after I switched to the "new" debugging flow today: https://expensify.slack.com/archives/C01GTK53T8Q/p1626422647390900?thread_ts=1626297548.276300&cid=C01GTK53T8Q

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's related to the "old" chrome debugger not being used

@kidroca
Copy link
Contributor Author

kidroca commented Jul 16, 2021

@marcaaron
I'm about to open a continuation PR for Onyx.printMetrics

Since the update for Reanimated 2 (TurboModules/JSI)
It's no longer possible to use the old (Chrome) debugging flow

react-native runtime does not implement the console.table we're using to print information
It was provided by Chrome, by launching the (old) debug flow

The other PR adds MD table formatting like this
image

Which would allow you to paste data like this:

Onyx Benchmark

  • Total: 13.4min
  • Last call finished at: 31.95sec
method total time spent max min avg time last call completed calls made
Onyx:set 1.1min 19.48sec 120.607ms 2.25sec 31.95sec 30
Onyx:getAllKeys 8.8min 6.27sec 0.140ms 1.90sec 30.64sec 277
Onyx:merge 48.43sec 19.49sec 31.937ms 1.73sec 31.95sec 28
Onyx:mergeCollection 7.83sec 2.60sec 663.751ms 1.57sec 31.95sec 5
Onyx:get 2.6min 19.12sec 0.064ms 751.025ms 30.63sec 207

Copy link
Contributor

@marcaaron marcaaron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good to me. Left a couple questions about the performance.now() workaround, but won't block on them.

@@ -6,6 +6,11 @@ import _ from 'underscore';
*/
let stats = {};

/* For some reason `performance.now()` does not start from `0` but a very large offset
* like `508,080,000` see: https://github.com/facebook/react-native/issues/30069
* Capturing an offset allows us to record start/ends times relative to app launch time */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, since it is supposed to be more reliable than Date, but still has this issue? 🤔

Not a blocker, but I'm not sure I'd expect it this to be 0. performance.now() returns elapsed since the time origin (or is supposed to at least).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it will never be 0 but the origin is definitely not app launch the benchmark would say something like "Last call finished at: 3940min" which is useless

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it that makes more sense to me now. Thanks for the explanation.

@@ -20,7 +25,7 @@ function decorateWithMetrics(func, alias = func.name) {
stats[alias] = [];

function decorated(...args) {
const startTime = performance.now();
const startTime = performance.now() - APP_LAUNCH_TIME;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to understand the reliability of this next usage of performance.now() here and which metric this will make more reliable. Is it just the endTime? Since all the other metrics are relative to performance.now() but that one will tell us the actual time from when Onyx started doing work and when it finished for each method?

Copy link
Contributor Author

@kidroca kidroca Jul 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't make anything more or less reliable, just keeps our start/end times relative to app launch

Differences between performance.now() are reliable but the initial time given by performance.now() is ridiculously high - and I can't match the value to anything - it's not the current unix ts, it's not the time since app launch
It's a value like 508 million and increases as time passes. Might be relative to midnight 00:00 UTC ? But that doesn't help us track boot time 😄

On the old flow, when this was provided by Chrome, the value will be very close to 0 initially and so you know a value of 1000 means something started/ended a second past app launch

By capturing our own reference point APP_LAUNCH_TIME we keep start/end times relative to that point
so we have more useful information

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remove this, I'll get this ATM: "Last call finished at: 8907.4min" so it's not midnight
It might be the time since last reboot, let me check
Yep seems to be it: "Last call finished at: 10.0min"
I guess it uses some clock managed by the OS and that's what it returns

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha, ok awesome, thanks for the explanation.
Very weird, but now that we are interested in something besides relative times also very necessary.

@marcaaron marcaaron merged commit c0e30e6 into Expensify:master Jul 16, 2021
@marcaaron
Copy link
Contributor

@kidroca ah that's annoying, I wasn't expecting an effect like that from updating that library 🤔 but the markdown table looks very slick 👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants