@samitouri / QOS-React-2 / commits / acbba1ae67

Updates to perf

ReactDefaultPerf: * Show times as float instead of string. This means they're sortable. * Add count columns to all types and average to exclusive time. * Include mountComponent where updateComponent time is measured. * Increment count on _renderValidatedComponent instead of update. ReactDefaultPerfAnalysis: * Return counts with all summaries.

Josh Duck committed Feb 13, 2014 at 18:11 UTC acbba1ae6720612019c1afbeafc08b6e2153e261
2 files changed +55 -39
src/test/ReactDefaultPerf.js
+29 -16
@@ -26,8 +26,12 @@ var ReactPerf = require('ReactPerf');
26
27 var performanceNow = require('performanceNow');
28
29 +function roundFloat(val) {
30 + return Math.floor(val * 100) / 100;
31 +}
32 +
33 var ReactDefaultPerf = {
30 - _allMeasurements: null, // last item in the list is the current one
34 + _allMeasurements: [], // last item in the list is the current one
35 _injected: false,
36
37 start: function() {
@@ -35,7 +39,7 @@ var ReactDefaultPerf = {
39 ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure);
40 }
41
38 - ReactDefaultPerf._allMeasurements = [];
42 + ReactDefaultPerf._allMeasurements.length = 0;
43 ReactPerf.enableMeasure = true;
44 },
45
@@ -53,8 +57,10 @@ var ReactDefaultPerf = {
57 console.table(summary.map(function(item) {
58 return {
59 'Component class name': item.componentName,
56 - 'Exclusive time': item.exclusiveTime.toFixed(2) + ' ms',
57 - 'Inclusive time': item.inclusiveTime.toFixed(2) + ' ms'
60 + 'Total inclusive time (ms)': roundFloat(item.inclusive),
61 + 'Total exclusive time (ms)': roundFloat(item.exclusive),
62 + 'Exclusive time per instance (ms)': roundFloat(item.exclusive / item.count),
63 + 'Instances': item.count
64 };
65 }));
66 console.log(
@@ -69,7 +75,8 @@ var ReactDefaultPerf = {
75 console.table(summary.map(function(item) {
76 return {
77 'Owner > component': item.componentName,
72 - 'Inclusive time': item.inclusiveTime.toFixed(2) + ' ms'
78 + 'Inclusive time (ms)': roundFloat(item.time),
79 + 'Instances': item.count
80 };
81 }));
82 console.log(
@@ -87,7 +94,8 @@ var ReactDefaultPerf = {
94 console.table(summary.map(function(item) {
95 return {
96 'Owner > component': item.componentName,
90 - 'Wasted time': item.inclusiveTime.toFixed(2) + ' ms'
97 + 'Wasted time (ms)': item.time,
98 + 'Instances': item.count
99 };
100 }));
101 console.log(
@@ -195,27 +203,32 @@ var ReactDefaultPerf = {
203 }
204 return rv;
205 } else if (moduleName === 'ReactCompositeComponent' && (
206 + fnName === 'mountComponent' ||
207 fnName === 'updateComponent' || // TODO: receiveComponent()?
208 fnName === '_renderValidatedComponent')) {
200 - var isInclusive = fnName === 'updateComponent';
209 +
210 + var rootNodeID = fnName === 'mountComponent' ?
211 + args[0] :
212 + this._rootNodeID;
213 + var isRender = fnName === '_renderValidatedComponent';
214 var entry = ReactDefaultPerf._allMeasurements[
215 ReactDefaultPerf._allMeasurements.length - 1
216 ];
204 - if (isInclusive) {
205 - // Since both updateComponent() and _renderValidatedComponent() are
206 - // called for each render, only record the count for one of them.
207 - entry.counts[this._rootNodeID] = entry.counts[this._rootNodeID] || 0;
208 - entry.counts[this._rootNodeID] += 1;
217 +
218 + if (isRender) {
219 + entry.counts[rootNodeID] = entry.counts[rootNodeID] || 0;
220 + entry.counts[rootNodeID] += 1;
221 }
222 +
223 start = performanceNow();
224 rv = func.apply(this, args);
225 totalTime = performanceNow() - start;
226
214 - var typeOfLog = isInclusive ? entry.inclusive : entry.exclusive;
215 - typeOfLog[this._rootNodeID] = typeOfLog[this._rootNodeID] || 0;
216 - typeOfLog[this._rootNodeID] += totalTime;
227 + var typeOfLog = isRender ? entry.exclusive : entry.inclusive;
228 + typeOfLog[rootNodeID] = typeOfLog[rootNodeID] || 0;
229 + typeOfLog[rootNodeID] += totalTime;
230
218 - entry.displayNames[this._rootNodeID] = {
231 + entry.displayNames[rootNodeID] = {
232 current: this.constructor.displayName,
233 owner: this._owner ? this._owner.constructor.displayName : '<root>'
234 };
src/test/ReactDefaultPerfAnalysis.js
+26 -23
@@ -77,8 +77,10 @@ function getExclusiveSummary(measurements) {
77 displayName = measurement.displayNames[id].current;
78
79 candidates[displayName] = candidates[displayName] || {
80 + componentName: displayName,
81 inclusive: 0,
81 - exclusive: 0
82 + exclusive: 0,
83 + count: 0
84 };
85 if (measurement.exclusive[id]) {
86 candidates[displayName].exclusive += measurement.exclusive[id];
@@ -86,32 +88,30 @@ function getExclusiveSummary(measurements) {
88 if (measurement.inclusive[id]) {
89 candidates[displayName].inclusive += measurement.inclusive[id];
90 }
91 + if (measurement.counts[id]) {
92 + candidates[displayName].count += measurement.counts[id];
93 + }
94 }
95 }
96
97 // Now make a sorted array with the results.
98 var arr = [];
99 for (displayName in candidates) {
95 - if (candidates[displayName].exclusiveTime < DONT_CARE_THRESHOLD) {
96 - continue;
100 + if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) {
101 + arr.push(candidates[displayName]);
102 }
98 - arr.push({
99 - componentName: displayName,
100 - exclusiveTime: candidates[displayName].exclusive,
101 - inclusiveTime: candidates[displayName].inclusive
102 - });
103 }
104
105 arr.sort(function(a, b) {
106 - return b.exclusiveTime - a.exclusiveTime;
106 + return b.exclusive - a.exclusive;
107 });
108
109 return arr;
110 }
111
112 function getInclusiveSummary(measurements, onlyClean) {
113 - var inclusiveTimes = {};
114 - var displayName;
113 + var candidates = {};
114 + var inclusiveKey;
115
116 for (var i = 0; i < measurements.length; i++) {
117 var measurement = measurements[i];
@@ -127,35 +127,38 @@ function getInclusiveSummary(measurements, onlyClean) {
127 continue;
128 }
129
130 - displayName = measurement.displayNames[id];
130 + var displayName = measurement.displayNames[id];
131
132 // Inclusive time is not useful for many components without knowing where
133 // they are instantiated. So we aggregate inclusive time with both the
134 // owner and current displayName as the key.
135 - var inclusiveKey = displayName.owner + ' > ' + displayName.current;
135 + inclusiveKey = displayName.owner + ' > ' + displayName.current;
136
137 - inclusiveTimes[inclusiveKey] = inclusiveTimes[inclusiveKey] || 0;
137 + candidates[inclusiveKey] = candidates[inclusiveKey] || {
138 + componentName: inclusiveKey,
139 + time: 0,
140 + count: 0
141 + };
142
143 if (measurement.inclusive[id]) {
140 - inclusiveTimes[inclusiveKey] += measurement.inclusive[id];
144 + candidates[inclusiveKey].time += measurement.inclusive[id];
145 + }
146 + if (measurement.counts[id]) {
147 + candidates[inclusiveKey].count += measurement.counts[id];
148 }
149 }
150 }
151
152 // Now make a sorted array with the results.
153 var arr = [];
147 - for (displayName in inclusiveTimes) {
148 - if (inclusiveTimes[displayName] < DONT_CARE_THRESHOLD) {
149 - continue;
154 + for (inclusiveKey in candidates) {
155 + if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) {
156 + arr.push(candidates[inclusiveKey]);
157 }
151 - arr.push({
152 - componentName: displayName,
153 - inclusiveTime: inclusiveTimes[displayName]
154 - });
158 }
159
160 arr.sort(function(a, b) {
158 - return b.inclusiveTime - a.inclusiveTime;
161 + return b.time - a.time;
162 });
163
164 return arr;