Chrome DevTools: Show native javascript functions in Profile performance analysis

This article is translated from Chrome DevTools: Show native functions in JS Profile . The Chinese version was first published in the V8 source code and surroundings of my Zhihu column .

In Chrome DevTools, you can use profiler to view the execution performance of native functions:

Native functions are part of the JavaScript language. These functions are different from custom functions written by developers. When we look at the call stack of the code in the profiler, these functions are filtered out. All we see in the profiler is the code written by ourselves.

When we capture the call stack, Chrome does not capture functions written in C++. However, many javascript native functions in the V8 engine are written in javascript language .

V8 uses JavaScript itself to implement most of the built-in objects and functions of the JavaScript language. For example, the promise function is written in JavaScript. We call such built-in functions self-hosted.

If we turn on the "Show native functions" setting, Chrome will display these functions in the profiler.

How does the Chrome profiler work

To find the most time-consuming code, the Chrome profiler captures a stack trace every 100μs.

This means that if a function only needs 50μs execution time, it may not be displayed in the analyzer!

When you analyze the time over a few milliseconds, you can know exactly when the application spends the most time. However, when you zoom in on the profiler panel to see more accurate time, the information will become less accurate.

The analyzer will also be inconsistent. Each time it is run, it produces a slightly different result. Sometimes very short function calls may be recorded, and running these function calls at other times may lose information.

Through this blog post, I will show you how to capture and analyze the performance of native functions. When you run the code yourself, the results may vary.

Array.join

First, we run the following code:

var arr = []
for (var i=0; i<1000; i++){
    arr.push(i)
}
console.profile("Array.join")
arr.join(",")
console.profileEnd("Array.join")

Select the "Chart" view of the profiler:

In the first analysis, we did not select "Show native functions":

When we run it again, enable "Show native functions":

When we point the mouse to the function, we will see more detailed information:

In the above information, chrome devtools shows the line number of the native function, you can find this file "array.js" in Chrome code search . The line number information may be different, because the latest version of the V8 source code may be different from the V8 version used by Chrome.

You can see the ArrayJoinfunction internally calls InnerArrayJoin:

function ArrayJoin(separator) {
  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join");

  var array = TO_OBJECT(this);
  var length = TO_LENGTH(array.length);

  return InnerArrayJoin(separator, array, length);
}

InnerArrayJoinCalled internally DoJoin.

DoJoinCalled %StringBuilderJoin.

%StringBuilderJoin It is implemented using C++.

Sparse array

We are a bit off topic, but I think V8's handling of sparse arrays (new Array(n)) is very interesting.

Why is this useful?

How does the following code work?

arr = new Array(10000000)
for (var i=0; i<10000; i++){
    arr.push(i)
}
console.profile("arr + arr")
arr + arr

console.profileEnd("arr + arr")

You usually do not perform addition operations on two arrays. But for some reason, some code I've seen recently does just that.

When not looking at the native function, we saw an anonymous function call.

When we turned to see the native function feature, Chrome calls arraythe toStringmethod, then calls the joinmethod.

Error().stack

Let's look at a different example. In JavaScript, you can Error().stackget a stack trace function is currently running (stack trace).

When we run the code, we made a total of two things: First, we create a new Errorobject, and then access its stackproperties.

It took a lot of time to get the string description information of the stack trace.

I was able to speed up the code I'm working on is by getting a Error object: Only when I need to display stack trace, only to resolve their stackproperty.

Inaccurate place

In the opening chapter of my article, I mentioned that very small time intervals may cause inaccurate results. To illustrate this point, I run on different computer configurations to another Error().stackcode segment.

We see the FormatErrorStringfunction, whereas in the previous analysis, this function does not show up.

(The total execution time this time is ~1ms, which means Chrome needs 10 samples of the call stack. The example above took ~10ms because I called it 10 times in the loop Error().stack.)

Related Reading

If you are interested in the V8 engine, I will talk about the V8 engine with you at 8 pm on April 15 (Saturday): Front-end programmers should know a little bit about V8-SegmentFault Lecture Hall .

Guess you like

Origin blog.csdn.net/justjavac/article/details/68063314