<commit_before>/**
 * Copyright (C) 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.caliper;

import com.google.common.collect.*;

import java.util.*;

/**
 * Prints a report containing the tested values and the corresponding
 * measurements. Measurements are grouped by variable using indentation.
 * Alongside numeric values, quick-glance ascii art bar charts are printed.
 * Sample output:
 * <pre>
 *              benchmark                 d     ns logarithmic runtime
 * ConcatenationBenchmark 3.141592653589793   4397 ||||||||||||||||||||||||
 * ConcatenationBenchmark              -0.0    223 |||||||||||||||
 *     FormatterBenchmark 3.141592653589793  33999 ||||||||||||||||||||||||||||||
 *     FormatterBenchmark              -0.0  26399 |||||||||||||||||||||||||||||
 * </pre>
 */
final class ConsoleReport {

  private static final int bargraphWidth = 30;
  private static final String benchmarkKey = "benchmark";

  private final List<Parameter> parameters;
  private final Result result;
  private final List<Run> runs;

  private final double logMaxValue;
  private final int decimalDigits;
  private final double divideBy;
  private final String units;
  private final int measurementColumnLength;

  public ConsoleReport(Result result) {
    this.result = result;

    double minValue = Double.POSITIVE_INFINITY;
    double maxValue = 0;

    Multimap<String, String> nameToValues = LinkedHashMultimap.create();
    List<Parameter> parametersBuilder = new ArrayList<Parameter>();
    for (Map.Entry<Run, Double> entry : result.getMeasurements().entrySet()) {
      Run run = entry.getKey();
      double d = entry.getValue();

      minValue = minValue < d ? minValue : d;
      maxValue = maxValue > d ? maxValue : d;

      for (Map.Entry<String, String> parameter : run.getParameters().entrySet()) {
        String name = parameter.getKey();
        nameToValues.put(name, parameter.getValue());
      }

      nameToValues.put(benchmarkKey, run.getBenchmarkClass().getSimpleName());
    }

    for (Map.Entry<String, Collection<String>> entry : nameToValues.asMap().entrySet()) {
      Parameter parameter = new Parameter(entry.getKey(), entry.getValue());
      parametersBuilder.add(parameter);
    }

    for (Parameter parameter : parametersBuilder) {
      double[] measurements = new double[parameter.values.size()];
      for (Map.Entry<Run, Double> entry : result.getMeasurements().entrySet()) {
        Run run = entry.getKey();
        measurements[parameter.index(run)] += entry.getValue();
      }
      double total = 0;
      for (double value : measurements) {
        total += value;
      }
      double mean = total / measurements.length;
      double sum = 0;
      for (double value : measurements) {
        double distance = value - mean;
        sum += distance * distance;
      }
      parameter.stdDeviation = Math.sqrt(sum / measurements.length);
    }
<commit_msg>Cleaning up standard deviation docs and implementation.<commit_after>/**
 * Copyright (C) 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.caliper;

import com.google.common.collect.*;

import java.util.*;

/**
 * Prints a report containing the tested values and the corresponding
 * measurements. Measurements are grouped by variable using indentation.
 * Alongside numeric values, quick-glance ascii art bar charts are printed.
 * Sample output:
 * <pre>
 *              benchmark                 d     ns logarithmic runtime
 * ConcatenationBenchmark 3.141592653589793   4397 ||||||||||||||||||||||||
 * ConcatenationBenchmark              -0.0    223 |||||||||||||||
 *     FormatterBenchmark 3.141592653589793  33999 ||||||||||||||||||||||||||||||
 *     FormatterBenchmark              -0.0  26399 |||||||||||||||||||||||||||||
 * </pre>
 */
final class ConsoleReport {

  private static final int bargraphWidth = 30;
  private static final String benchmarkKey = "benchmark";

  private final List<Parameter> parameters;
  private final Result result;
  private final List<Run> runs;

  private final double logMaxValue;
  private final int decimalDigits;
  private final double divideBy;
  private final String units;
  private final int measurementColumnLength;

  public ConsoleReport(Result result) {
    this.result = result;

    double minValue = Double.POSITIVE_INFINITY;
    double maxValue = 0;

    Multimap<String, String> nameToValues = LinkedHashMultimap.create();
    List<Parameter> parametersBuilder = new ArrayList<Parameter>();
    for (Map.Entry<Run, Double> entry : result.getMeasurements().entrySet()) {
      Run run = entry.getKey();
      double d = entry.getValue();

      minValue = minValue < d ? minValue : d;
      maxValue = maxValue > d ? maxValue : d;

      for (Map.Entry<String, String> parameter : run.getParameters().entrySet()) {
        String name = parameter.getKey();
        nameToValues.put(name, parameter.getValue());
      }

      nameToValues.put(benchmarkKey, run.getBenchmarkClass().getSimpleName());
    }

    for (Map.Entry<String, Collection<String>> entry : nameToValues.asMap().entrySet()) {
      Parameter parameter = new Parameter(entry.getKey(), entry.getValue());
      parametersBuilder.add(parameter);
    }

    /*
     * Figure out how much influence each parameter has on the measured value.
     * We sum the measurements taken with each value of each parameter. For
     * parameters that have influence on the measurement, the sums will differ
     * by value. If the parameter has little influence, the sums will be similar
     * to one another and close to the overall average. We take the standard
     * deviation across each parameters collection of sums. Higher standard
     * deviation implies higher influence on the measured result.
     */
    double sumOfAllMeasurements = 0;
    for (double measurement : result.getMeasurements().values()) {
      sumOfAllMeasurements += measurement;
    }
    double mean = sumOfAllMeasurements / result.getMeasurements().size();
    for (Parameter parameter : parametersBuilder) {
      int numValues = parameter.values.size();
      double[] sumForValue = new double[numValues];
      for (Map.Entry<Run, Double> entry : result.getMeasurements().entrySet()) {
        Run run = entry.getKey();
        sumForValue[parameter.index(run)] += entry.getValue();
      }
      double stdDeviationSquared = 0;
      for (double value : sumForValue) {
        double distance = value - mean;
        stdDeviationSquared += distance * distance;
      }
      parameter.stdDeviation = Math.sqrt(stdDeviationSquared / numValues);
    }

{'fraction_non_alphanumeric': 0.11538963581777836, 'fraction_numerical': 0.01723012661532437, 'mean_word_length': 3.3069139966273187, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '357108', 'n_tokens_mistral': 2159, 'n_tokens_neox': 2034, 'n_words': 681}