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