Add very basic read benchmark

This commit is contained in:
Alex Barney 2019-01-21 12:58:25 -06:00
parent b6964589fa
commit 30b42eaf34
4 changed files with 72 additions and 5 deletions

View file

@ -1,6 +1,7 @@
// Adapted from https://gist.github.com/0ab6a96899cc5377bf54 // Adapted from https://gist.github.com/0ab6a96899cc5377bf54
using System; using System;
using System.Diagnostics;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
@ -13,6 +14,10 @@ namespace LibHac
private long _total; private long _total;
private readonly Timer _timer; private readonly Timer _timer;
private bool _isMeasuringSpeed;
private Stopwatch _watch;
private long _timedBytes;
private readonly TimeSpan _animationInterval = TimeSpan.FromSeconds(1.0 / 30); private readonly TimeSpan _animationInterval = TimeSpan.FromSeconds(1.0 / 30);
private const string Animation = @"|/-\"; private const string Animation = @"|/-\";
@ -36,6 +41,7 @@ namespace LibHac
public void ReportAdd(long value) public void ReportAdd(long value)
{ {
Interlocked.Add(ref _progress, value); Interlocked.Add(ref _progress, value);
if (_isMeasuringSpeed) Interlocked.Add(ref _timedBytes, value);
} }
public void LogMessage(string message) public void LogMessage(string message)
@ -52,6 +58,38 @@ namespace LibHac
Report(0); Report(0);
} }
public void StartNewStopWatch()
{
_isMeasuringSpeed = true;
_timedBytes = 0;
_watch = Stopwatch.StartNew();
}
public void PauseStopWatch()
{
_isMeasuringSpeed = false;
_watch.Stop();
}
public void ResumeStopWatch()
{
_isMeasuringSpeed = true;
if (_watch == null)
{
_watch = Stopwatch.StartNew();
}
else
{
_watch.Start();
}
}
public string GetRateString()
{
return Util.GetBytesReadable((long) (_timedBytes / _watch.Elapsed.TotalSeconds)) + "/s";
}
private void TimerHandler(object state) private void TimerHandler(object state)
{ {
lock (_timer) lock (_timer)
@ -59,12 +97,18 @@ namespace LibHac
if (_disposed) return; if (_disposed) return;
string text = string.Empty; string text = string.Empty;
string speed = string.Empty;
if (_isMeasuringSpeed)
{
speed = $" {GetRateString()}";
}
if (_total > 0) if (_total > 0)
{ {
double progress = _total == 0 ? 0 : (double)_progress / _total; double progress = _total == 0 ? 0 : (double)_progress / _total;
int progressBlockCount = (int)Math.Min(progress * BlockCount, BlockCount); int progressBlockCount = (int)Math.Min(progress * BlockCount, BlockCount);
text = $"[{new string('#', progressBlockCount)}{new string('-', BlockCount - progressBlockCount)}] {_progress}/{_total} {progress:P1} {Animation[_animationIndex++ % Animation.Length]}"; text = $"[{new string('#', progressBlockCount)}{new string('-', BlockCount - progressBlockCount)}] {_progress}/{_total} {progress:P1} {Animation[_animationIndex++ % Animation.Length]}{speed}";
} }
UpdateText(text); UpdateText(text);

View file

@ -50,6 +50,7 @@ namespace hactoolnet
new CliOption("listromfs", 0, (o, a) => o.ListRomFs = true), new CliOption("listromfs", 0, (o, a) => o.ListRomFs = true),
new CliOption("listfiles", 0, (o, a) => o.ListFiles = true), new CliOption("listfiles", 0, (o, a) => o.ListFiles = true),
new CliOption("sign", 0, (o, a) => o.SignSave = true), new CliOption("sign", 0, (o, a) => o.SignSave = true),
new CliOption("readbench", 0, (o, a) => o.ReadBench = true),
new CliOption("title", 1, (o, a) => o.TitleId = ParseTitleId(a[0])), new CliOption("title", 1, (o, a) => o.TitleId = ParseTitleId(a[0])),
new CliOption("bench", 1, (o, a) => o.BenchType = a[0]), new CliOption("bench", 1, (o, a) => o.BenchType = a[0]),
@ -161,7 +162,7 @@ namespace hactoolnet
sb.AppendLine(" -y, --verify Verify all hashes in the input file."); sb.AppendLine(" -y, --verify Verify all hashes in the input file.");
sb.AppendLine(" -h, --enablehash Enable hash checks when reading the input file."); sb.AppendLine(" -h, --enablehash Enable hash checks when reading the input file.");
sb.AppendLine(" -k, --keyset Load keys from an external file."); sb.AppendLine(" -k, --keyset Load keys from an external file.");
sb.AppendLine(" -t, --intype=type Specify input file type [nca, xci, romfs, pk11, pk21, ini1, kip1, switchfs, save, ndv0 keygen]"); sb.AppendLine(" -t, --intype=type Specify input file type [nca, xci, romfs, pk11, pk21, ini1, kip1, switchfs, save, ndv0, keygen]");
sb.AppendLine(" --titlekeys <file> Load title keys from an external file."); sb.AppendLine(" --titlekeys <file> Load title keys from an external file.");
sb.AppendLine("NCA options:"); sb.AppendLine("NCA options:");
sb.AppendLine(" --plaintext <file> Specify file path for saving a decrypted copy of the NCA."); sb.AppendLine(" --plaintext <file> Specify file path for saving a decrypted copy of the NCA.");

View file

@ -43,6 +43,7 @@ namespace hactoolnet
public bool ListRomFs; public bool ListRomFs;
public bool ListFiles; public bool ListFiles;
public bool SignSave; public bool SignSave;
public bool ReadBench;
public ulong TitleId; public ulong TitleId;
public string BenchType; public string BenchType;
@ -80,6 +81,6 @@ namespace hactoolnet
{ {
public Options Options; public Options Options;
public Keyset Keyset; public Keyset Keyset;
public IProgressReport Logger; public ProgressBar Logger;
} }
} }

View file

@ -52,7 +52,7 @@ namespace hactoolnet
} }
} }
if (ctx.Options.RomfsOutDir != null || ctx.Options.RomfsOut != null) if (ctx.Options.RomfsOutDir != null || ctx.Options.RomfsOut != null || ctx.Options.ReadBench)
{ {
NcaSection section = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs || x?.Type == SectionType.Bktr); NcaSection section = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs || x?.Type == SectionType.Bktr);
@ -78,6 +78,27 @@ namespace hactoolnet
IFileSystem romfs = nca.OpenSectionFileSystem(section.SectionNum, ctx.Options.IntegrityLevel); IFileSystem romfs = nca.OpenSectionFileSystem(section.SectionNum, ctx.Options.IntegrityLevel);
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger); romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
} }
if (ctx.Options.ReadBench)
{
long bytesToRead = 1024L * 1024 * 1024 * 5;
IStorage storage = nca.OpenSection(section.SectionNum, false, ctx.Options.IntegrityLevel, true);
var dest = new NullStorage(storage.Length);
int iterations = (int)(bytesToRead / storage.Length) + 1;
ctx.Logger.LogMessage(iterations.ToString());
ctx.Logger.StartNewStopWatch();
for (int i = 0; i < iterations; i++)
{
storage.CopyTo(dest, ctx.Logger);
ctx.Logger.LogMessage(ctx.Logger.GetRateString());
}
ctx.Logger.PauseStopWatch();
ctx.Logger.LogMessage(ctx.Logger.GetRateString());
}
} }
if (ctx.Options.ExefsOutDir != null || ctx.Options.ExefsOut != null) if (ctx.Options.ExefsOutDir != null || ctx.Options.ExefsOut != null)
@ -113,7 +134,7 @@ namespace hactoolnet
nca.OpenDecryptedNca().WriteAllBytes(ctx.Options.PlaintextOut, ctx.Logger); nca.OpenDecryptedNca().WriteAllBytes(ctx.Options.PlaintextOut, ctx.Logger);
} }
ctx.Logger.LogMessage(nca.Print()); if (!ctx.Options.ReadBench) ctx.Logger.LogMessage(nca.Print());
} }
} }