blob: bd745be95c6b317d76fa85fd06d721bfe02e96bb [file] [log] [blame]
using Lucene.Net.Benchmarks.ByTask.Stats;
using Lucene.Net.Benchmarks.ByTask.Utils;
using System;
using System.Collections.Generic;
using System.Text;
using JCG = J2N.Collections.Generic;
namespace Lucene.Net.Benchmarks.ByTask.Tasks
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/// <summary>
/// Report (abstract) task - all report tasks extend this task.
/// </summary>
public abstract class ReportTask : PerfTask
{
public ReportTask(PerfRunData runData)
: base(runData)
{
}
/// <seealso cref="PerfTask.ShouldNeverLogAtStart"/>
protected override bool ShouldNeverLogAtStart
{
get { return true; }
}
/// <seealso cref="PerfTask.ShouldNotRecordStats"/>
protected override bool ShouldNotRecordStats
{
get { return true; }
}
/// <summary>
/// From here start the code used to generate the reports.
/// Subclasses would use this part to generate reports.
/// </summary>
protected static readonly string newline = Environment.NewLine;
/// <summary>
/// Get a textual summary of the benchmark results, average from all test runs.
/// </summary>
protected static readonly string OP = "Operation ";
protected static readonly string ROUND = " round";
protected static readonly string RUNCNT = " runCnt";
protected static readonly string RECCNT = " recsPerRun";
protected static readonly string RECSEC = " rec/s";
protected static readonly string ELAPSED = " elapsedSec";
protected static readonly string USEDMEM = " avgUsedMem";
protected static readonly string TOTMEM = " avgTotalMem";
protected static readonly string[] COLS = {
RUNCNT,
RECCNT,
RECSEC,
ELAPSED,
USEDMEM,
TOTMEM
};
/// <summary>
/// Compute a title line for a report table.
/// </summary>
/// <param name="longestOp">Size of longest op name in the table.</param>
/// <returns>The table title line.</returns>
protected virtual string TableTitle(string longestOp)
{
StringBuilder sb = new StringBuilder();
sb.Append(Formatter.Format(OP, longestOp));
sb.Append(ROUND);
sb.Append(RunData.Config.GetColsNamesForValsByRound());
for (int i = 0; i < COLS.Length; i++)
{
sb.Append(COLS[i]);
}
return sb.ToString();
}
/// <summary>
/// Find the longest op name out of completed tasks.
/// </summary>
/// <param name="taskStats">Completed tasks to be considered.</param>
/// <returns>The longest op name out of completed tasks.</returns>
protected virtual string LongestOp(IEnumerable<TaskStats> taskStats)
{
string longest = OP;
foreach (TaskStats stat in taskStats)
{
if (stat.Elapsed >= 0)
{ // consider only tasks that ended
string name = stat.Task.GetName();
if (name.Length > longest.Length)
{
longest = name;
}
}
}
return longest;
}
/// <summary>
/// Compute a report line for the given task stat.
/// </summary>
/// <param name="longestOp">Size of longest op name in the table.</param>
/// <param name="stat">Task stat to be printed.</param>
/// <returns>The report line.</returns>
protected virtual string TaskReportLine(string longestOp, TaskStats stat)
{
PerfTask task = stat.Task;
StringBuilder sb = new StringBuilder();
sb.Append(Formatter.Format(task.GetName(), longestOp));
string round = (stat.Round >= 0 ? "" + stat.Round : "-");
sb.Append(Formatter.FormatPaddLeft(round, ROUND));
sb.Append(RunData.Config.GetColsValuesForValsByRound(stat.Round));
sb.Append(Formatter.Format(stat.NumRuns, RUNCNT));
sb.Append(Formatter.Format(stat.Count / stat.NumRuns, RECCNT));
long elapsed = (stat.Elapsed > 0 ? stat.Elapsed : 1); // assume at least 1ms
sb.Append(Formatter.Format(2, (float)(stat.Count * 1000.0 / elapsed), RECSEC));
sb.Append(Formatter.Format(2, (float)stat.Elapsed / 1000, ELAPSED));
sb.Append(Formatter.Format(0, (float)stat.MaxUsedMem / stat.NumRuns, USEDMEM));
sb.Append(Formatter.Format(0, (float)stat.MaxTotMem / stat.NumRuns, TOTMEM));
return sb.ToString();
}
protected virtual Report GenPartialReport(int reported, JCG.LinkedDictionary<string, TaskStats> partOfTasks, int totalSize)
{
string longetOp = LongestOp(partOfTasks.Values);
bool first = true;
StringBuilder sb = new StringBuilder();
sb.Append(TableTitle(longetOp));
sb.Append(newline);
int lineNum = 0;
foreach (TaskStats stat in partOfTasks.Values)
{
if (!first)
{
sb.Append(newline);
}
first = false;
string line = TaskReportLine(longetOp, stat);
lineNum++;
if (partOfTasks.Count > 2 && lineNum % 2 == 0)
{
line = line.Replace(" ", " - ");
}
sb.Append(line);
int[] byTime = stat.GetCountsByTime();
if (byTime != null)
{
sb.Append(newline);
int end = -1;
for (int i = byTime.Length - 1; i >= 0; i--)
{
if (byTime[i] != 0)
{
end = i;
break;
}
}
if (end != -1)
{
sb.Append(" by time:");
for (int i = 0; i < end; i++)
{
sb.Append(' ').Append(byTime[i]);
}
}
}
}
string reptxt = (reported == 0 ? "No Matching Entries Were Found!" : sb.ToString());
return new Report(reptxt, partOfTasks.Count, reported, totalSize);
}
}
}