Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6313)

Unified Diff: chrome/browser/resources/profiler.js

Issue 8590001: Cache the results of merging/filtering/grouping data in about:profiler. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Make comment better Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/profiler.js
===================================================================
--- chrome/browser/resources/profiler.js (revision 110261)
+++ chrome/browser/resources/profiler.js (working copy)
@@ -5,10 +5,6 @@
var g_browserBridge;
var g_mainView;
-// TODO(eroman): Don't repeat the work of grouping, sorting, merging on every
-// redraw. Rather do it only once when one of its dependencies
-// change and cache the result.
-
/**
* Main entry point called once the page has loaded.
*/
@@ -723,48 +719,6 @@
// --------------------------------------------------------------------------
/**
- * Selects all the data in |rows| which are matched by |filterFunc|, and
- * buckets the results using |entryToGroupKeyFunc|. For each bucket aggregates
- * are computed, and the results are sorted.
- *
- * Returns a dictionary whose keys are the group name, and the value is an
- * objected containing two properties: |rows| and |aggregates|.
- */
- function prepareData(rows, entryToGroupKeyFunc, filterFunc, sortingFunc) {
- var groupedData = {};
-
- for (var i = 0; i < rows.length; ++i) {
- var e = rows[i];
-
- if (!filterFunc(e))
- continue; // Not matched by our filter, discard the row.
-
- var groupKey = entryToGroupKeyFunc(e);
-
- var groupData = groupedData[groupKey];
- if (!groupData) {
- groupData = {
- aggregates: initializeAggregates(ALL_KEYS),
- rows: [],
- };
- groupedData[groupKey] = groupData;
- }
-
- // Add the row to our list.
- groupData.rows.push(e);
-
- // Update aggregates for each column.
- consumeAggregates(groupData.aggregates, e);
- }
-
- // Sort all the data.
- for (var groupKey in groupedData)
- groupedData[groupKey].rows.sort(sortingFunc);
-
- return groupedData;
- }
-
- /**
* Adds new derived properties to row. Mutates the provided dictionary |e|.
*/
function augmentDataRow(e) {
@@ -913,12 +867,12 @@
/**
* Renders the information for a particular group.
*/
- function drawGroup(parent, groupKey, groupData, columns,
+ function drawGroup(parent, groupData, columns,
columnOnClickHandler, currentSortKeys) {
var div = addNode(parent, 'div');
div.className = 'group-container';
- drawGroupTitle(div, groupKey);
+ drawGroupTitle(div, groupData.key);
var table = addNode(div, 'table');
@@ -1211,38 +1165,96 @@
// Add our computed properties.
augmentDataRow(newRow);
- this.allData_.push(newRow);
+ this.flatData_.push(newRow);
}
+ // Recompute the merged data based on flatData_.
+ this.updateMergedData_();
+ },
+
+ updateMergedData_: function() {
+ // Recompute mergedData_.
+ this.mergedData_ = mergeRows(this.flatData_,
+ this.getMergeColumns_(),
+ this.shouldMergeSimilarThreads_());
+
+ // Recompute filteredData_ (since it is derived from mergedData_)
+ this.updateFilteredData_();
+ },
+
+ updateFilteredData_: function() {
+ // Recompute filteredData_.
+ this.filteredData_ = [];
+ var filterFunc = this.getFilterFunction_();
+ for (var i = 0; i < this.mergedData_.length; ++i) {
+ var r = this.mergedData_[i];
+ if (!filterFunc(r)) {
+ // Not matched by our filter, discard.
+ continue;
+ }
+ this.filteredData_.push(r);
+ }
+
+ // Recompute groupedData_ (since it is derived from filteredData_)
+ this.updateGroupedData_();
+ },
+
+ updateGroupedData_: function() {
+ // Recompute groupedData_.
+ var groupKeyToData = {};
+ var entryToGroupKeyFunc = this.getGroupingFunction_();
+ for (var i = 0; i < this.filteredData_.length; ++i) {
+ var r = this.filteredData_[i];
+
+ var groupKey = entryToGroupKeyFunc(r);
+
+ var groupData = groupKeyToData[groupKey];
+ if (!groupData) {
+ groupData = {
+ key: JSON.parse(groupKey),
+ aggregates: initializeAggregates(ALL_KEYS),
+ rows: [],
+ };
+ groupKeyToData[groupKey] = groupData;
+ }
+
+ // Add the row to our list.
+ groupData.rows.push(r);
+
+ // Update aggregates for each column.
+ consumeAggregates(groupData.aggregates, r);
+ }
+ this.groupedData_ = groupKeyToData;
+
+ // Figure out a display order for the groups themselves.
+ this.sortedGroupKeys_ = getDictionaryKeys(groupKeyToData);
+ this.sortedGroupKeys_.sort(this.getGroupSortingFunction_());
+
+ // Sort the group data.
+ this.sortGroupedData_();
+ },
+
+ sortGroupedData_: function() {
+ var sortingFunc = this.getSortingFunction_();
+ for (var k in this.groupedData_)
+ this.groupedData_[k].rows.sort(sortingFunc);
+
+ // Every cached data dependency is now up to date, all that is left is
+ // to actually draw the result.
this.redrawData_();
},
- redrawData_: function() {
- // Eliminate columns which we are merging on.
- var mergedKeys = this.getMergeColumns_();
- var data = mergeRows(
- this.allData_, mergedKeys, this.shouldMergeSimilarThreads_());
-
+ getVisibleColumnKeys_: function() {
// Figure out what columns to include, based on the selected checkboxes.
var columns = this.getSelectionColumns_();
- deleteValuesFromArray(columns, mergedKeys);
- // Group, aggregate, filter, and sort the data.
- var groupedData = prepareData(
- data, this.getGroupingFunction_(), this.getFilterFunction_(),
- this.getSortingFunction_());
+ // Eliminate columns which we are merging on.
+ deleteValuesFromArray(columns, this.getMergeColumns_());
- // Figure out a display order for the groups.
- var groupKeys = getDictionaryKeys(groupedData);
- groupKeys.sort(this.getGroupSortingFunction_());
-
- // Clear the results div, sine we may be overwriting older data.
- var parent = $(RESULTS_DIV_ID);
- parent.innerHTML = '';
-
- if (groupKeys.length > 0) {
+ // Eliminate columns which we are grouped on.
+ if (this.sortedGroupKeys_.length > 0) {
// The grouping will be the the same for each so just pick the first.
- var randomGroupKey = JSON.parse(groupKeys[0]);
+ var randomGroupKey = this.groupedData_[this.sortedGroupKeys_[0]].key;
// The grouped properties are going to be the same for each row in our,
// table, so avoid drawing them in our table!
@@ -1254,21 +1266,46 @@
deleteValuesFromArray(columns, keysToExclude);
}
+ return columns;
+ },
+
+ redrawData_: function() {
+ // Clear the results div, sine we may be overwriting older data.
+ var parent = $(RESULTS_DIV_ID);
+ parent.innerHTML = '';
+
+ var columns = this.getVisibleColumnKeys_();
+
var columnOnClickHandler = this.onClickColumn_.bind(this);
// Draw each group.
- for (var i = 0; i < groupKeys.length; ++i) {
- var groupKeyString = groupKeys[i];
- var groupData = groupedData[groupKeyString];
- var groupKey = JSON.parse(groupKeyString);
-
- drawGroup(parent, groupKey, groupData, columns,
+ for (var i = 0; i < this.sortedGroupKeys_.length; ++i) {
+ var groupData = this.groupedData_[this.sortedGroupKeys_[i]];
+ drawGroup(parent, groupData, columns,
columnOnClickHandler, this.currentSortKeys_);
}
},
init_: function() {
- this.allData_ = [];
+ // Data goes through the following pipeline:
jar (doing other things) 2011/11/17 02:40:31 This sort of comment is quite helpful.
+ // (1) Raw data received from browser, and transformed into our own
+ // internal row format (where properties are indexed by KEY_*
+ // constants.)
+ // (2) We "augment" each row by adding some extra computed columns
+ // (like averages).
+ // (3) The rows are merged using current merge settings.
+ // (4) The rows that don't match current search expression are
+ // tossed out.
+ // (5) The rows are organized into "groups" based on current settings,
+ // and aggregate values are computed for each resulting group.
+ // (6) The rows within each group are sorted using current settings.
+ // (7) The grouped rows are drawn to the screen.
+ this.flatData_ = [];
+ this.mergedData_ = [];
+ this.filteredData_ = [];
+ this.groupedData_ = {};
+ this.sortedGroupKeys_ = [];
+
this.fillSelectionCheckboxes_($(COLUMN_TOGGLES_CONTAINER_ID));
this.fillMergeCheckboxes_($(COLUMN_MERGE_TOGGLES_CONTAINER_ID));
@@ -1385,13 +1422,13 @@
onChangedGrouping_: function(select, i) {
updateKeyListFromDropdown(this.currentGroupingKeys_, i, select);
this.fillGroupingDropdowns_();
- this.redrawData_();
+ this.updateGroupedData_();
},
onChangedSorting_: function(select, i) {
updateKeyListFromDropdown(this.currentSortKeys_, i, select);
this.fillSortingDropdowns_();
- this.redrawData_();
+ this.sortGroupedData_();
},
onSelectCheckboxChanged_: function() {
@@ -1399,15 +1436,15 @@
},
onMergeCheckboxChanged_: function() {
- this.redrawData_();
+ this.updateMergedData_();
},
onMergeSimilarThreadsCheckboxChanged_: function() {
- this.redrawData_();
+ this.updateMergedData_();
},
onChangedFilter_: function() {
- this.redrawData_();
+ this.updateFilteredData_();
},
/**
@@ -1456,7 +1493,7 @@
}
this.fillSortingDropdowns_();
- this.redrawData_();
+ this.sortGroupedData_();
},
getSortingFunction_: function() {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698