diff --git a/src/test/ReactDefaultPerf.js b/src/test/ReactDefaultPerf.js index 46c27c4014..bed9d055f0 100644 --- a/src/test/ReactDefaultPerf.js +++ b/src/test/ReactDefaultPerf.js @@ -26,8 +26,12 @@ var ReactPerf = require('ReactPerf'); var performanceNow = require('performanceNow'); +function roundFloat(val) { + return Math.floor(val * 100) / 100; +} + var ReactDefaultPerf = { - _allMeasurements: null, // last item in the list is the current one + _allMeasurements: [], // last item in the list is the current one _injected: false, start: function() { @@ -35,7 +39,7 @@ var ReactDefaultPerf = { ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure); } - ReactDefaultPerf._allMeasurements = []; + ReactDefaultPerf._allMeasurements.length = 0; ReactPerf.enableMeasure = true; }, @@ -53,8 +57,10 @@ var ReactDefaultPerf = { console.table(summary.map(function(item) { return { 'Component class name': item.componentName, - 'Exclusive time': item.exclusiveTime.toFixed(2) + ' ms', - 'Inclusive time': item.inclusiveTime.toFixed(2) + ' ms' + 'Total inclusive time (ms)': roundFloat(item.inclusive), + 'Total exclusive time (ms)': roundFloat(item.exclusive), + 'Exclusive time per instance (ms)': roundFloat(item.exclusive / item.count), + 'Instances': item.count }; })); console.log( @@ -69,7 +75,8 @@ var ReactDefaultPerf = { console.table(summary.map(function(item) { return { 'Owner > component': item.componentName, - 'Inclusive time': item.inclusiveTime.toFixed(2) + ' ms' + 'Inclusive time (ms)': roundFloat(item.time), + 'Instances': item.count }; })); console.log( @@ -87,7 +94,8 @@ var ReactDefaultPerf = { console.table(summary.map(function(item) { return { 'Owner > component': item.componentName, - 'Wasted time': item.inclusiveTime.toFixed(2) + ' ms' + 'Wasted time (ms)': item.time, + 'Instances': item.count }; })); console.log( @@ -195,27 +203,32 @@ var ReactDefaultPerf = { } return rv; } else if (moduleName === 'ReactCompositeComponent' && ( + fnName === 'mountComponent' || fnName === 'updateComponent' || // TODO: receiveComponent()? fnName === '_renderValidatedComponent')) { - var isInclusive = fnName === 'updateComponent'; + + var rootNodeID = fnName === 'mountComponent' ? + args[0] : + this._rootNodeID; + var isRender = fnName === '_renderValidatedComponent'; var entry = ReactDefaultPerf._allMeasurements[ ReactDefaultPerf._allMeasurements.length - 1 ]; - if (isInclusive) { - // Since both updateComponent() and _renderValidatedComponent() are - // called for each render, only record the count for one of them. - entry.counts[this._rootNodeID] = entry.counts[this._rootNodeID] || 0; - entry.counts[this._rootNodeID] += 1; + + if (isRender) { + entry.counts[rootNodeID] = entry.counts[rootNodeID] || 0; + entry.counts[rootNodeID] += 1; } + start = performanceNow(); rv = func.apply(this, args); totalTime = performanceNow() - start; - var typeOfLog = isInclusive ? entry.inclusive : entry.exclusive; - typeOfLog[this._rootNodeID] = typeOfLog[this._rootNodeID] || 0; - typeOfLog[this._rootNodeID] += totalTime; + var typeOfLog = isRender ? entry.exclusive : entry.inclusive; + typeOfLog[rootNodeID] = typeOfLog[rootNodeID] || 0; + typeOfLog[rootNodeID] += totalTime; - entry.displayNames[this._rootNodeID] = { + entry.displayNames[rootNodeID] = { current: this.constructor.displayName, owner: this._owner ? this._owner.constructor.displayName : '' }; diff --git a/src/test/ReactDefaultPerfAnalysis.js b/src/test/ReactDefaultPerfAnalysis.js index 4ad832d175..2dceaee1b3 100644 --- a/src/test/ReactDefaultPerfAnalysis.js +++ b/src/test/ReactDefaultPerfAnalysis.js @@ -77,8 +77,10 @@ function getExclusiveSummary(measurements) { displayName = measurement.displayNames[id].current; candidates[displayName] = candidates[displayName] || { + componentName: displayName, inclusive: 0, - exclusive: 0 + exclusive: 0, + count: 0 }; if (measurement.exclusive[id]) { candidates[displayName].exclusive += measurement.exclusive[id]; @@ -86,32 +88,30 @@ function getExclusiveSummary(measurements) { if (measurement.inclusive[id]) { candidates[displayName].inclusive += measurement.inclusive[id]; } + if (measurement.counts[id]) { + candidates[displayName].count += measurement.counts[id]; + } } } // Now make a sorted array with the results. var arr = []; for (displayName in candidates) { - if (candidates[displayName].exclusiveTime < DONT_CARE_THRESHOLD) { - continue; + if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) { + arr.push(candidates[displayName]); } - arr.push({ - componentName: displayName, - exclusiveTime: candidates[displayName].exclusive, - inclusiveTime: candidates[displayName].inclusive - }); } arr.sort(function(a, b) { - return b.exclusiveTime - a.exclusiveTime; + return b.exclusive - a.exclusive; }); return arr; } function getInclusiveSummary(measurements, onlyClean) { - var inclusiveTimes = {}; - var displayName; + var candidates = {}; + var inclusiveKey; for (var i = 0; i < measurements.length; i++) { var measurement = measurements[i]; @@ -127,35 +127,38 @@ function getInclusiveSummary(measurements, onlyClean) { continue; } - displayName = measurement.displayNames[id]; + var displayName = measurement.displayNames[id]; // Inclusive time is not useful for many components without knowing where // they are instantiated. So we aggregate inclusive time with both the // owner and current displayName as the key. - var inclusiveKey = displayName.owner + ' > ' + displayName.current; + inclusiveKey = displayName.owner + ' > ' + displayName.current; - inclusiveTimes[inclusiveKey] = inclusiveTimes[inclusiveKey] || 0; + candidates[inclusiveKey] = candidates[inclusiveKey] || { + componentName: inclusiveKey, + time: 0, + count: 0 + }; if (measurement.inclusive[id]) { - inclusiveTimes[inclusiveKey] += measurement.inclusive[id]; + candidates[inclusiveKey].time += measurement.inclusive[id]; + } + if (measurement.counts[id]) { + candidates[inclusiveKey].count += measurement.counts[id]; } } } // Now make a sorted array with the results. var arr = []; - for (displayName in inclusiveTimes) { - if (inclusiveTimes[displayName] < DONT_CARE_THRESHOLD) { - continue; + for (inclusiveKey in candidates) { + if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) { + arr.push(candidates[inclusiveKey]); } - arr.push({ - componentName: displayName, - inclusiveTime: inclusiveTimes[displayName] - }); } arr.sort(function(a, b) { - return b.inclusiveTime - a.inclusiveTime; + return b.time - a.time; }); return arr;