Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 <title>Telemetry Performance Test Results</title> | 4 <title>Telemetry Performance Test Results</title> |
| 5 <style type="text/css"> | 5 <style type="text/css"> |
| 6 | 6 |
| 7 section { | 7 section { |
| 8 background: white; | 8 background: white; |
| 9 padding: 10px; | 9 padding: 10px; |
| 10 position: relative; | 10 position: relative; |
| (...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 591 }).reduce(function (markup, cell) { return markup + cell; }, '') + '</tr></h ead><tbody></tbody>'); | 591 }).reduce(function (markup, cell) { return markup + cell; }, '') + '</tr></h ead><tbody></tbody>'); |
| 592 | 592 |
| 593 var testNames = []; | 593 var testNames = []; |
| 594 for (testName in tests) | 594 for (testName in tests) |
| 595 testNames.push(testName); | 595 testNames.push(testName); |
| 596 | 596 |
| 597 window.isFirstImportantRow = true; | 597 window.isFirstImportantRow = true; |
| 598 | 598 |
| 599 testNames.sort().map(function (testName) { | 599 testNames.sort().map(function (testName) { |
| 600 var test = tests[testName]; | 600 var test = tests[testName]; |
| 601 if (test.isMemoryTest() != shouldIgnoreMemory) | 601 if (test.isMemoryTest() != shouldIgnoreMemory) { |
| 602 createTableRow(runs, test, referenceIndex, useLargeLinePlots); | 602 new TableRow(runs, test, referenceIndex, useLargeLinePlots); |
|
Sami
2014/10/20 16:24:47
I assume the upcoming CL will keep a reference to
picksi1
2014/10/24 15:04:59
The object created will be used a lot in the follo
| |
| 603 } | |
| 603 }); | 604 }); |
| 604 | 605 |
| 605 $('.closeButton').click(function(event) { | 606 $('.closeButton').click(function(event) { |
| 606 for (var i = 0; i < runs.length; i++) { | 607 for (var i = 0; i < runs.length; i++) { |
| 607 if (runs[i].id() == event.target.parentNode.id) { | 608 if (runs[i].id() == event.target.parentNode.id) { |
| 608 runs[i].hide(); | 609 runs[i].hide(); |
| 609 undeleteManager.ondelete(runs[i].id()); | 610 undeleteManager.ondelete(runs[i].id()); |
| 610 location.reload(); | 611 location.reload(); |
| 611 break; | 612 break; |
| 612 } | 613 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 675 var intercept = sumY / points.length - slope * sumX / points.length; | 676 var intercept = sumY / points.length - slope * sumX / points.length; |
| 676 return {slope: slope, intercept: intercept, rSquared: r * r}; | 677 return {slope: slope, intercept: intercept, rSquared: r * r}; |
| 677 } | 678 } |
| 678 | 679 |
| 679 var warningSign = '<svg viewBox="0 0 100 100" style="width: 18px; height: 18px; vertical-align: bottom;" version="1.1">' | 680 var warningSign = '<svg viewBox="0 0 100 100" style="width: 18px; height: 18px; vertical-align: bottom;" version="1.1">' |
| 680 + '<polygon fill="red" points="50,10 90,80 10,80 50,10" stroke="red" stroke- width="10" stroke-linejoin="round" />' | 681 + '<polygon fill="red" points="50,10 90,80 10,80 50,10" stroke="red" stroke- width="10" stroke-linejoin="round" />' |
| 681 + '<polygon fill="white" points="47,30 48,29, 50, 28.7, 52,29 53,30 50,60" s troke="white" stroke-width="10" stroke-linejoin="round" />' | 682 + '<polygon fill="white" points="47,30 48,29, 50, 28.7, 52,29 53,30 50,60" s troke="white" stroke-width="10" stroke-linejoin="round" />' |
| 682 + '<circle cx="50" cy="73" r="6" fill="white" />' | 683 + '<circle cx="50" cy="73" r="6" fill="white" />' |
| 683 + '</svg>'; | 684 + '</svg>'; |
| 684 | 685 |
| 685 function createTableRow(runs, test, referenceIndex, useLargeLinePlots) { | 686 function TableRow(runs, test, referenceIndex, useLargeLinePlots) { |
| 686 var tableRow = $('<tr><td class="test collapsed"' + (test.isImportant ? ' st yle="font-weight:bold"' : '') + '>' + test.name() + '</td><td class="unit">' + t est.unit() + '</td></tr>'); | 687 this.runs = runs; |
| 688 this.test = test; | |
| 689 this.referenceIndex = referenceIndex; | |
| 690 this.useLargeLinePlots = useLargeLinePlots; | |
| 687 | 691 |
| 688 function markupForRun(result, referenceResult) { | 692 this.tableRow = $('<tr><td class="test collapsed"' + (this.test.isImportant ? ' style="font-weight:bold"' : '') + '>' + this.test.name() + '</td><td class=" unit">' + this.test.unit() + '</td></tr>'); |
| 689 var comparisonCell = ''; | |
| 690 var hiddenValue = ''; | |
| 691 var shouldCompare = result !== referenceResult; | |
| 692 if (shouldCompare && referenceResult) { | |
| 693 var percentDifference = referenceResult.percentDifference(result); | |
| 694 var better = test.biggerIsBetter() ? percentDifference > 0 : percent Difference < 0; | |
| 695 var comparison = ''; | |
| 696 var className = 'comparison'; | |
| 697 if (referenceResult.isStatisticallySignificant(result)) { | |
| 698 comparison = formatPercentage(Math.abs(percentDifference)) + (be tter ? ' Better' : ' Worse '); | |
| 699 className += better ? ' better' : ' worse'; | |
| 700 } | |
| 701 hiddenValue = '<span style="display: none">|' + comparison + '</span >'; | |
| 702 comparisonCell = '<td class="' + className + '">' + comparison + '</ td>'; | |
| 703 } else if (shouldCompare) | |
| 704 comparisonCell = '<td class="comparison"></td>'; | |
| 705 | |
| 706 var values = result.values(); | |
| 707 var warning = ''; | |
| 708 var regressionAnalysis = ''; | |
| 709 if (result.histogramValues) { | |
| 710 // Don't calculate regression result for histograms. | |
| 711 } | |
| 712 else if (values && values.length > 3) { | |
| 713 regressionResult = linearRegression(values); | |
| 714 regressionAnalysis = 'slope=' + toFixedWidthPrecision(regressionResu lt.slope) | |
| 715 + ', R^2=' + toFixedWidthPrecision(regressionResult.rSquared); | |
| 716 if (regressionResult.rSquared > 0.6 && Math.abs(regressionResult.slo pe) > 0.01) { | |
| 717 warning = ' <span class="regression-warning" title="Detected a t ime dependency with ' + regressionAnalysis + '">' + warningSign + ' </span>'; | |
| 718 } | |
| 719 } | |
| 720 | |
| 721 var statistics = 'σ=' + toFixedWidthPrecision(result.confidenceInt ervalDelta()) + ', min=' + toFixedWidthPrecision(result.min()) | |
| 722 + ', max=' + toFixedWidthPrecision(result.max()) + '\n' + regression Analysis; | |
| 723 | |
| 724 // Tablesorter doesn't know about the second cell so put the comparison in the invisible element. | |
| 725 return '<td class="result" title="' + statistics + '">' + toFixedWidthPr ecision(result.mean()) + hiddenValue | |
| 726 + '</td><td class="confidenceIntervalDelta" title="' + statistics + '">± ' | |
| 727 + formatPercentage(result.confidenceIntervalDeltaRatio()) + warning + '</td>' + comparisonCell; | |
| 728 } | |
| 729 | |
| 730 function markupForMissingRun(isReference) { | |
| 731 return '<td colspan="' + (isReference ? 2 : 3) + '" class="missing">Miss ing</td>'; | |
| 732 } | |
| 733 | 693 |
| 734 var runIndex = 0; | 694 var runIndex = 0; |
| 735 var results = test.results(); | 695 var results = this.test.results(); |
| 736 var referenceResult = undefined; | 696 var referenceResult = undefined; |
| 737 var resultIndexMap = {}; | 697 var resultIndexMap = {}; |
| 738 for (var i = 0; i < results.length; i++) { | 698 for (var i = 0; i < results.length; i++) { |
| 739 while (runs[runIndex] !== results[i].run()) | 699 while (this.runs[runIndex] !== results[i].run()) |
| 740 runIndex++; | 700 runIndex++; |
| 741 if (runIndex == referenceIndex) | 701 if (runIndex == this.referenceIndex) |
| 742 referenceResult = results[i]; | 702 referenceResult = results[i]; |
| 743 resultIndexMap[runIndex] = i; | 703 resultIndexMap[runIndex] = i; |
| 744 } | 704 } |
| 745 for (var i = 0; i < runs.length; i++) { | 705 for (var i = 0; i < this.runs.length; i++) { |
| 746 var resultIndex = resultIndexMap[i]; | 706 var resultIndex = resultIndexMap[i]; |
| 747 if (resultIndex == undefined) | 707 if (resultIndex == undefined) |
| 748 tableRow.append(markupForMissingRun(i == referenceIndex)); | 708 this.tableRow.append(this.markupForMissingRun(i == this.referenceInd ex)); |
| 749 else | 709 else |
| 750 tableRow.append(markupForRun(results[resultIndex], referenceResult)) ; | 710 this.tableRow.append(this.markupForRun(results[resultIndex], this.re ferenceResult)); |
| 751 } | 711 } |
| 752 | 712 |
| 753 $('#container').children('tbody').last().append(tableRow); | 713 $('#container').children('tbody').last().append(this.tableRow); |
| 754 | 714 |
| 755 function toggle() { | 715 if (this.test.isImportant && window.isFirstImportantRow) { |
| 756 var firstCell = tableRow.children('td').first(); | 716 window.isFirstImportantRow = false; |
| 757 if (firstCell.children('section').length) { | 717 this.toggle(); |
| 758 firstCell.children('section').remove(); | 718 } |
| 759 tableRow.children('td').css({'padding-bottom': ''}); | 719 |
| 760 tableRow.children('td').first().addClass('collapsed'); | 720 var owningObject = this; |
| 761 tableRow.children('td').first().removeClass('expanded'); | 721 this.tableRow.click(function(event) { |
| 762 } else { | 722 if (event.target != owningObject.tableRow[0] && event.target.parentNode != owningObject.tableRow[0]) { |
| 763 var plot = createPlot(firstCell, test, useLargeLinePlots); | 723 return; |
| 764 plot.css({'position': 'absolute', 'z-index': 2}); | |
| 765 var offset = tableRow.offset(); | |
| 766 offset.left += 1; | |
| 767 offset.top += tableRow.outerHeight(); | |
| 768 plot.offset(offset); | |
| 769 tableRow.children('td').css({'padding-bottom': plot.outerHeight() + 5}); | |
| 770 tableRow.children('td').first().removeClass('collapsed'); | |
| 771 tableRow.children('td').first().addClass('expanded'); | |
| 772 } | 724 } |
| 725 event.preventDefault(); | |
| 726 owningObject.toggle(); | |
| 727 }); | |
| 728 } | |
| 773 | 729 |
| 774 return false; | 730 TableRow.prototype.markupForRun = function(result, referenceResult) { |
| 775 }; | 731 var comparisonCell = ''; |
| 732 var hiddenValue = ''; | |
| 733 var shouldCompare = result !== referenceResult; | |
| 734 if (shouldCompare && referenceResult) { | |
| 735 var percentDifference = referenceResult.percentDifference(result); | |
| 736 var better = this.test.biggerIsBetter() ? percentDifference > 0 : percen tDifference < 0; | |
| 737 var comparison = ''; | |
| 738 var className = 'comparison'; | |
| 739 if (referenceResult.isStatisticallySignificant(result)) { | |
| 740 comparison = formatPercentage(Math.abs(percentDifference)) + (better ? ' Better' : ' Worse '); | |
| 741 className += better ? ' better' : ' worse'; | |
| 742 } | |
| 743 hiddenValue = '<span style="display: none">|' + comparison + '</span>'; | |
| 744 comparisonCell = '<td class="' + className + '">' + comparison + '</td>' ; | |
| 745 } else if (shouldCompare) | |
| 746 comparisonCell = '<td class="comparison"></td>'; | |
| 776 | 747 |
| 777 tableRow.click(function(event) { | 748 var values = result.values(); |
| 778 if (event.target != tableRow[0] && event.target.parentNode != tableRow[0 ]) | 749 var warning = ''; |
| 779 return; | 750 var regressionAnalysis = ''; |
| 751 if (result.histogramValues) { | |
| 752 // Don't calculate regression result for histograms. | |
| 753 } else if (values && values.length > 3) { | |
| 754 regressionResult = linearRegression(values); | |
| 755 regressionAnalysis = 'slope=' + toFixedWidthPrecision(regressionResult.s lope) | |
| 756 + ', R^2=' + toFixedWidthPrecision(regressionResult.rSquared); | |
| 757 if (regressionResult.rSquared > 0.6 && Math.abs(regressionResult.slope) > 0.01) { | |
| 758 warning = ' <span class="regression-warning" title="Detected a time dependency with ' + regressionAnalysis + '">' + warningSign + ' </span>'; | |
| 759 } | |
| 760 } | |
| 780 | 761 |
| 781 event.preventDefault(); | 762 var statistics = 'σ=' + toFixedWidthPrecision(result.confidenceInterva lDelta()) + ', min=' + toFixedWidthPrecision(result.min()) |
| 763 + ', max=' + toFixedWidthPrecision(result.max()) + '\n' + regressionAnal ysis; | |
| 782 | 764 |
| 783 toggle(); | 765 // Tablesorter doesn't know about the second cell so put the comparison in t he invisible element. |
| 784 }); | 766 return '<td class="result" title="' + statistics + '">' + toFixedWidthPrecis ion(result.mean()) + hiddenValue |
| 767 + '</td><td class="confidenceIntervalDelta" title="' + statistics + '">& plusmn; ' | |
| 768 + formatPercentage(result.confidenceIntervalDeltaRatio()) + warning + '< /td>' + comparisonCell; | |
| 769 } | |
| 785 | 770 |
| 786 if (test.isImportant && window.isFirstImportantRow) { | 771 TableRow.prototype.markupForMissingRun = function(isReference) { |
| 787 window.isFirstImportantRow = false; | 772 return '<td colspan="' + (isReference ? 2 : 3) + '" class="missing">Missing< /td>'; |
| 788 toggle(); | 773 } |
| 774 | |
| 775 TableRow.prototype.toggle = function() { | |
| 776 var firstCell = this.tableRow.children('td').first(); | |
| 777 if (firstCell.children('section').length) { | |
| 778 firstCell.children('section').remove(); | |
| 779 this.tableRow.children('td').css({'padding-bottom': ''}); | |
| 780 this.tableRow.children('td').first().addClass('collapsed'); | |
| 781 this.tableRow.children('td').first().removeClass('expanded'); | |
| 782 } else { | |
| 783 var plot = createPlot(firstCell, this.test, this.useLargeLinePlots); | |
| 784 plot.css({'position': 'absolute', 'z-index': 2}); | |
| 785 var offset = this.tableRow.offset(); | |
| 786 offset.left += 1; | |
| 787 offset.top += this.tableRow.outerHeight(); | |
| 788 plot.offset(offset); | |
| 789 this.tableRow.children('td').css({'padding-bottom': plot.outerHeight() + 5}); | |
| 790 this.tableRow.children('td').first().removeClass('collapsed'); | |
| 791 this.tableRow.children('td').first().addClass('expanded'); | |
| 789 } | 792 } |
| 793 | |
| 794 return false; | |
| 790 } | 795 } |
| 791 | 796 |
| 792 function init() { | 797 function init() { |
| 793 $.tablesorter.addParser({ | 798 $.tablesorter.addParser({ |
| 794 id: 'comparison', | 799 id: 'comparison', |
| 795 is: function(s) { | 800 is: function(s) { |
| 796 return s.indexOf('|') >= 0; | 801 return s.indexOf('|') >= 0; |
| 797 }, | 802 }, |
| 798 format: function(s) { | 803 format: function(s) { |
| 799 var parsed = parseFloat(s.substring(s.indexOf('|') + 1)); | 804 var parsed = parseFloat(s.substring(s.indexOf('|') + 1)); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 879 } else { | 884 } else { |
| 880 $('#undelete').hide(); | 885 $('#undelete').hide(); |
| 881 } | 886 } |
| 882 } | 887 } |
| 883 | 888 |
| 884 </script> | 889 </script> |
| 885 <script id="results-json" type="application/json">%json_results%</script> | 890 <script id="results-json" type="application/json">%json_results%</script> |
| 886 <script id="units-json" type="application/json">%json_units%</script> | 891 <script id="units-json" type="application/json">%json_units%</script> |
| 887 </body> | 892 </body> |
| 888 </html> | 893 </html> |
| OLD | NEW |