- From: Boris Zbarsky <bzbarsky@mit.edu>
- Date: Thu, 12 Feb 2015 20:25:31 -0500
- To: Nat Duca <nduca@google.com>
- CC: Ilya Grigorik <igrigorik@google.com>, Philippe Le Hegaret <plh@w3.org>, public-web-perf <public-web-perf@w3.org>, Eli Perelman <eperelman@mozilla.com>
On 2/12/15 7:15 PM, Nat Duca wrote:
> Most of these tools operate in a "record, do something, stop recording
> and get events" mode. The idea with those approaches is that you can
> buffer cheaply, and only do expensive work during the get events stage.
Right, I understand that.
I guess the fundamental assumption here is that saving all the
information needed to reify a PerformanceEntry later in a C++ struct or
something is cheaper than actually creating a PerformanceEntry object,
right? But is that necessarily true? I suppose you can play games with
some sort of rarely-reallocing slab allocator deal for the structs that
are harder to do for PerformanceEntry objects...
> But, if an observer is registered, if we do this wrong, then we can get
> in a situation where we're create PerformanceEntry objects thousands of
> times a frame. My hope is we could avoid that situation.
I guess what confuses me is what part of PerformanceEntry object
allocation is necessarily expensive.
To be concrete, in the two cases I know best, Gecko and Servo, the
situation is as follows:
Servo needs to allocate the objects probably out of SpiderMonkey's GC
arena. So it's equivalent to the allocation of any other JS object; the
main issue is probably the GC pressure.
Gecko allocates PerformanceEntry objects via |new| in C++. There's the
malloc overhead, but no interaction with SpiderMonkey and no GC
pressure. This is assuming that we're not immediately sticking them in
a JS array, of course.
I guess both could try to do something more clever if they could create
the PerformanceEntry objects lazily, but the clever thing may not end up
that much faster than calling |new|.
> Talking to our v8 peeps, we can't take plain array types and lazily
> create them.
Yes, I agree, if the object is an actual JS array then you can't do the
lazy thing very easily and then you do get GC pressure.
> As I think about it, maybe there shouldn't be any index/etc getters and
> only an AsSequence(). Eg:
>
> interface LazyPerformanceEntryList {
> bool HasEntryNamed(string);
> PerformanceEntryList AsList();
> }
>
> That way you have to explicitly ask for the entries.
This is sounding a lot more likely to not seem crazy to web developers,
yes. ;)
> But such a direction change hinges on you buying my argument that the
> observer callbacks should have overhead only proportional to the
> callback, rather than the size of the event list being delivered.
I don't think you can entirely avoid the latter, just because you still
have to store the data and whatnot. We're just talking about the size
of the constants.
But yes, I can buy wanting to reduce GC pressure and wanting to keep the
constant for adding to the buffer as low as possible.
-Boris
Received on Friday, 13 February 2015 01:26:10 UTC