[internal] disposable performance helpers
This commit is contained in:
Родитель
54aa51c653
Коммит
3a5eb2e0ce
|
@ -0,0 +1,93 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
namespace Xamarin.Forms.Build.Tasks
|
||||
{
|
||||
[Preserve(AllMembers = true)]
|
||||
internal class PerformanceProvider : IPerformanceProvider
|
||||
{
|
||||
internal class Statistic
|
||||
{
|
||||
public readonly List<Tuple<string, long>> StartTimes = new List<Tuple<string, long>>();
|
||||
public int CallCount;
|
||||
public long TotalTime;
|
||||
public bool IsDetail;
|
||||
}
|
||||
|
||||
readonly Dictionary<string, Statistic> _Statistics = new Dictionary<string, Statistic>();
|
||||
|
||||
public Dictionary<string, Statistic> Statistics {
|
||||
get { return _Statistics; }
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Statistics.Clear();
|
||||
}
|
||||
|
||||
public void Start(string reference, string tag = null, [CallerFilePath] string path = null, [CallerMemberName] string member = null)
|
||||
{
|
||||
string id = GetId(tag, path, member);
|
||||
|
||||
Statistic stats = GetStat(id);
|
||||
|
||||
if (tag != null)
|
||||
stats.IsDetail = true;
|
||||
|
||||
stats.CallCount++;
|
||||
stats.StartTimes.Add(new Tuple<string, long>(reference, Stopwatch.GetTimestamp()));
|
||||
}
|
||||
|
||||
public void Stop(string reference, string tag = null, [CallerFilePath] string path = null, [CallerMemberName] string member = null)
|
||||
{
|
||||
string id = GetId(tag, path, member);
|
||||
long stop = Stopwatch.GetTimestamp();
|
||||
|
||||
Statistic stats = GetStat(id);
|
||||
|
||||
if (!stats.StartTimes.Any())
|
||||
return;
|
||||
|
||||
long start = stats.StartTimes.Single(s => s.Item1 == reference).Item2;
|
||||
stats.TotalTime += stop - start;
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetStats()
|
||||
{
|
||||
yield return "ID | Call Count | Total Time | Avg Time";
|
||||
foreach (KeyValuePair<string, Statistic> kvp in Statistics.OrderBy(kvp => kvp.Key)) {
|
||||
string key = ShortenPath(kvp.Key);
|
||||
double total = TimeSpan.FromTicks(kvp.Value.TotalTime).TotalMilliseconds;
|
||||
double avg = total / kvp.Value.CallCount;
|
||||
yield return string.Format("{0,-80} | {1,-10} | {2,-10}ms | {3,-8}ms", key, kvp.Value.CallCount, total, avg);
|
||||
}
|
||||
}
|
||||
|
||||
static string ShortenPath(string path)
|
||||
{
|
||||
int index = path.IndexOf("Xamarin.Forms.");
|
||||
if (index > -1)
|
||||
path = path.Substring(index + 14);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static string GetId(string tag, string path, string member)
|
||||
{
|
||||
return string.Format("{0}:{1}{2}", path, member, (tag != null ? "-" + tag : string.Empty));
|
||||
}
|
||||
|
||||
Statistic GetStat(string id)
|
||||
{
|
||||
Statistic stats;
|
||||
if (!Statistics.TryGetValue(id, out stats)) {
|
||||
Statistics[id] = stats = new Statistic();
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System;
|
||||
|
||||
namespace Xamarin.Forms.Internals
|
||||
{
|
||||
|
@ -30,5 +31,32 @@ namespace Xamarin.Forms.Internals
|
|||
{
|
||||
Provider?.Stop(reference, tag, path, member);
|
||||
}
|
||||
|
||||
internal static IDisposable StartNew(string tag = null, [CallerFilePath] string path = null, [CallerMemberName] string member = null)
|
||||
{
|
||||
return new DisposablePerformanceReference(tag, path, member);
|
||||
}
|
||||
|
||||
class DisposablePerformanceReference : IDisposable
|
||||
{
|
||||
string _reference;
|
||||
string _tag;
|
||||
string _path;
|
||||
string _member;
|
||||
|
||||
public DisposablePerformanceReference(string tag, string path, string member)
|
||||
{
|
||||
_reference = Guid.NewGuid().ToString();
|
||||
_tag = tag;
|
||||
_path = path;
|
||||
_member = member;
|
||||
Start(_reference, _tag, _path, _member);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Stop(_reference, _tag, _path, _member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче