All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.diirt.graphene.profile.utils.ProfileAnalysis Maven / Gradle / Ivy

There is a newer version: 3.1.7
Show newest version
/**
 * Copyright (C) 2010-14 diirt developers. See COPYRIGHT.TXT
 * All rights reserved. Use is subject to license terms. See LICENSE.TXT
 */
package org.diirt.graphene.profile.utils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import org.diirt.graphene.profile.ProfileGraph2D;
import org.diirt.graphene.profile.io.CSVFinder;
import org.diirt.graphene.profile.io.CSVReader;
import org.diirt.graphene.profile.io.CSVWriter;
import org.diirt.graphene.profile.io.DateUtils;

/**
 * Provides the tools necessary for comparing the output tables of profiling
 * to determine changes in the results.
 * 

* Provides options to analyze the two tables types: *

    *
  • ProfileGraph2D 1D tables
  • *
  • MultiLevelProfiler 2D tables
  • *
*

* The ProfileAnalysis class is purely static and unable * to be instantiated. *

* WARNING: the analysis operations assume the preconditions * are satisfied with only minor checks. Therefore it essential * that the appropriate file types are selected. * * @author asbarber */ public class ProfileAnalysis { /** * Private constructor; cannot be instantiated. */ private ProfileAnalysis(){}; /** * Percent level in which difference in values are considered statistically * significant and thus take appropriate (warning) action. */ public static final double STATISTICALLY_SIGNIFICANT = 0.05; /** * Brings a dialog box to ask the user to select two table based * CSV files and compares the differences of the tables. *

* Computes the difference of each cell between the first file selected * and the second file (first - second). *

* Precondition: both files selected are MultiLevelProfiler * table files of the same graph type. */ public static void compareTables2D(){ String message = "Select two Graphene table files (*.csv) to compute" + " the timing differences of."; String hint = "Note that the differences are calculated by:" + " first file cell minus second file cell."; JOptionPane.showMessageDialog(null, message); JOptionPane.showMessageDialog(null, hint); File fileA, fileB; fileA = CSVFinder.browseCSV(); if (fileA == null){ return; } fileB = CSVFinder.browseCSV(); if (fileB == null){ return; } compareTables2D(fileA, fileB); } /** * Computes the difference of each cell between the first file selected * and the second file (first - second). *

* Precondition: both files selected are MultiLevelProfiler * table files of the same graph type. * * @param fileA .CSV MultiLevelProfiler formatted file, * considered initial file (compares fileA - fileB) * @param fileB .CSV MultiLevelProfiler formatted file, * considered initial file (compares fileA - fileB) */ public static void compareTables2D(File fileA, File fileB){ CSVReader.validate2DTablesNames(fileA, fileB); List> dataA = CSVReader.parseCSV(fileA); List> dataB = CSVReader.parseCSV(fileB); CSVReader.validate2DTables(dataA, dataB); if (dataA.isEmpty() || dataB.isEmpty()){ return; } String badCell = "*Error in reading this cell*"; List output = new ArrayList<>(); //Header List outputHeader = new ArrayList<>(); for (int c = 0; c < dataA.get(0).size(); ++c){ //Entry in both headers are the same if (dataA.get(0).get(c).equals(dataB.get(0).get(c))){ outputHeader.add(dataA.get(0).get(c)); } //Different entry in dataA vs dataB else{ outputHeader.add(badCell); } } output.add(outputHeader); //Rows for (int r = 1; r < dataA.size(); ++r){ List outputRow = new ArrayList<>(); for (int c = 0; c < dataA.get(r).size(); ++c){ try{ double numA = Double.parseDouble(dataA.get(r).get(c)); double numB = Double.parseDouble(dataB.get(r).get(c)); double diff = (numA - numB) / numA * 100; outputRow.add(String.format("%.3f", diff + "%")); } catch (NumberFormatException ex){ outputRow.add(badCell); } } output.add(outputRow); } //Saving String[] compA = fileA.getName().split("-"); String[] compB = fileB.getName().split("-"); String date = DateUtils.getDate(DateUtils.DateFormat.NONDELIMITED), dateA = compA[0], dateB = compB[0], graphType = compA[1]; File outputFile = CSVWriter.createNewFile( ProfileGraph2D.LOG_FILEPATH + date + "-" + graphType + "-Table2D Difference-" + dateA + "vs" + dateB + ".csv"); CSVWriter.writeData(outputFile, output); } /** * Computes the difference between the last two records * in each 1D table and analyzes whether the change was significant. *

* Conditions to Analyze: *

    *
  • Supported files can be found
  • *
  • The 1D tables are in the right .CSV format
  • *
  • The file has two rows of data to compare
  • *
* * @return a list of: * for each 1D table analyzed, * a generated analysis message * including the graph profile and the * the results of the analysis (significant increase/decrease) */ public static List analyzeTables1D(){ List files = CSVFinder.findTables1D(); List results = new ArrayList<>(); //All files that are supported and found for (File tableFile: files){ if (tableFile != null){ List> tableRows = CSVReader.parseCSV(tableFile); //Includes a header plus two rows of data if (tableRows.size() > 2){ List previous = tableRows.get(tableRows.size() - 2); List recent = tableRows.get(tableRows.size() - 1); //Graph Type String graphType = previous.get(0); //Average Time double percentChange = percentChange( Double.parseDouble(previous.get(2)), Double.parseDouble(recent.get(2)) ); //Performance Change String performance = performanceChange( Double.parseDouble(previous.get(2)), Double.parseDouble(recent.get(2)) ); //Analysis results.add(graphType + ": " + performance + ": " + String.format("%.3f", percentChange) + "% changed" ); } } } results.add("\n" + results.size() + " files analyzed."); return results; } /** * Calculates the percent change from initial to final. * @param valInit initial value * @param valFinal final value * @return percent change (as decimal) */ public static double percentChange(double valInit, double valFinal){ return (valFinal - valInit) / valInit * 100; } /** * Determines the significance of the change from the initial value to * the final value. * @param valInit initial value * @param valFinal final value * @return message about the change in performance */ public static String performanceChange(double valInit, double valFinal){ double percentChange = percentChange(valInit, valFinal); //Signficant performance decrease if (percentChange > ProfileAnalysis.STATISTICALLY_SIGNIFICANT*100){ return "Performance Decrease"; } //Significant performance increase else if (percentChange < ProfileAnalysis.STATISTICALLY_SIGNIFICANT*100){ return "Performance Increase"; } //No Significant performance change else{ return "Performance Stable"; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy