Skip to content

File basic_formatter.cpp

File List > benchmark > exporter > basic_formatter.cpp

Go to the documentation of this file

#include "basic_formatter.h"

#include "benchmark/benchmark.h"
#include "common.h"
#include "format.h"
#include "workbook.h"
#include "worksheet.h"

namespace Argos {

void BasicFormatter::Fill(lxw_workbook *workbook,
                          const BenchmarkResult &result) {
  lxw_worksheet *ws = workbook_add_worksheet(workbook, "Result");

  lxw_format *num_fmt = createNumFormat(workbook);
  lxw_format *date_fmt = createDateFormat(workbook);

  // Pass 1: measure column widths
  ColumnWidthTracker tracker;
  measureMetadata(result, tracker);
  measureTableHeaders(result, tracker);
  measureTableData(result, tracker);
  tracker.applyToWorksheet(ws);

  // Pass 2: write data
  int row = 0;
  writeMetadata(ws, result, row, num_fmt, date_fmt);
  row++; // blank row before table
  writeTableHeaders(ws, result, row);
  writeTableData(ws, result, row, num_fmt);
}

// --- Formats ---

lxw_format *BasicFormatter::createNumFormat(lxw_workbook *workbook) {
  lxw_format *fmt = workbook_add_format(workbook);
  format_set_num_format(fmt, "0.000");
  return fmt;
}

lxw_format *BasicFormatter::createDateFormat(lxw_workbook *workbook) {
  lxw_format *fmt = workbook_add_format(workbook);
  format_set_num_format(fmt, "dd/mm/yyyy hh:mm:ss");
  return fmt;
}

// --- Measurement ---

void BasicFormatter::measureMetadata(const BenchmarkResult &result,
                                     ColumnWidthTracker &tracker) {
  tracker.measureString(0, "Date réalisation");
  tracker.measureString(1, "01/01/2024 12:00:00");

  tracker.measureString(0, "Num coeur CPU");
  tracker.measureInt(1, result.meta.num_cpus);

  tracker.measureString(0, "Fréquence CPU (MHz)");
  tracker.measureDouble(1, result.meta.mhz_per_cpu);
}

void BasicFormatter::measureTableHeaders(const BenchmarkResult &result,
                                         ColumnWidthTracker &tracker) {
  tracker.measureString(COL_NAME, "OBJ file name");
  tracker.measureString(COL_ITERATIONS, "iterations");
  tracker.measureString(COL_CPU_TIME, "CPU time / op (ms)");
  tracker.measureString(COL_WALL_TIME, "Overall time / op (ms)");

  int col = COL_METRICS;
  if (!result.results.empty()) {
    for (const auto &kv : result.results[0].metrics) {
      tracker.measureString(col++, kv.first);
    }
  }
}

void BasicFormatter::measureTableData(const BenchmarkResult &result,
                                      ColumnWidthTracker &tracker) {
  for (const auto &line : result.results) {
    tracker.measureString(COL_NAME, line.name);
    tracker.measureInt(COL_ITERATIONS, line.iterations);
    tracker.measureDouble(COL_CPU_TIME, line.cpu_time_per_op);
    tracker.measureDouble(COL_WALL_TIME, line.wall_time_per_op);

    int col = COL_METRICS;
    for (const auto &kv : line.metrics) {
      tracker.measureDouble(col++, kv.second.value);
    }
  }
}

// --- Writing ---

void BasicFormatter::writeMetadata(lxw_worksheet *ws,
                                   const BenchmarkResult &result, int &row,
                                   lxw_format *num_fmt, lxw_format *date_fmt) {
  lxw_datetime date = this->convert_time_t_to_lxw(result.meta.date_time);
  worksheet_write_string(ws, row, 0, "Date réalisation", NULL);
  worksheet_write_datetime(ws, row++, 1, &date, date_fmt);

  worksheet_write_string(ws, row, 0, "Num coeur CPU", NULL);
  worksheet_write_number(ws, row++, 1, result.meta.num_cpus, num_fmt);

  worksheet_write_string(ws, row, 0, "Fréquence CPU (MHz)", NULL);
  worksheet_write_number(ws, row, 1, result.meta.mhz_per_cpu, num_fmt);
}

void BasicFormatter::writeTableHeaders(lxw_worksheet *ws,
                                       const BenchmarkResult &result, int row) {
  int col = COL_NAME;
  worksheet_write_string(ws, row, col++, "OBJ file name", NULL);
  worksheet_write_string(ws, row, col++, "iterations", NULL);
  worksheet_write_string(ws, row, col++, "CPU time / op (ms)", NULL);
  worksheet_write_string(ws, row, col++, "Overall time / op (ms)", NULL);

  if (!result.results.empty()) {
    for (const auto &kv : result.results[0].metrics) {
      worksheet_write_string(ws, row, col++, kv.first.c_str(), NULL);
    }
  }
}

void BasicFormatter::writeTableData(lxw_worksheet *ws,
                                    const BenchmarkResult &result, int &row,
                                    lxw_format *num_fmt) {
  for (const auto &line : result.results) {
    ++row;
    int col = COL_NAME;

    worksheet_write_string(ws, row, col++, line.name.c_str(), NULL);
    worksheet_write_number(ws, row, col++, line.iterations, num_fmt);
    worksheet_write_number(ws, row, col++, line.cpu_time_per_op*1000, num_fmt);
    worksheet_write_number(ws, row, col++, line.wall_time_per_op*1000, num_fmt);

    for (const auto &kv : line.metrics) {
      worksheet_write_number(ws, row, col++, kv.second.value, num_fmt);
    }
  }
}

} // namespace Argos