2017-04-09 22 views
3

複数の場所で自分のプログラムで関数を実行するのにかかった時間を計測したいと考えています。関数のラッパークラスを測定する最善の方法は何ですか?

StopWatchを扱うと、コードがちょっと乱雑に思えるので、私はそれをラップすることにしました。

これらは私が必要なものです:戻り値:

  • 機能はしてもしなくてもよい、私は機能のうちの二つのことを取得する必要があり、戻り値
  • を有することができる非同期機能を受け取ることになりますそれが実行されるまでに要した秒数(秒単位)

複数のプロジェクトで使用されるため、読みやすく持続可能な解決法を見つけたいと思います。

public class TimeMeasurer 
{ 
private readonly Stopwatch _stopWatch; 

public TimeMeasurer() 
{ 
    _stopWatch = new Stopwatch(); 
} 

public async Task<Tuple<double, TReturn>> Start<TReturn>(Func<Task<TReturn>> function) 
{ 
    try 
    { 
     _stopWatch.Start(); 
     var val = await function(); 
     var took = _stopWatch.Elapsed.TotalSeconds; 

     return Tuple.Create(took, val); 
    } 
    finally 
    { 
     _stopWatch.Stop(); 
     _stopWatch.Reset(); 
    } 
} 

public async Task<double> Start(Func<Task> function) 
{ 
    try 
    { 
     _stopWatch.Start(); 
     await function(); 
     var took = _stopWatch.Elapsed.TotalSeconds; 

     return took; 
    } 
    finally 
    { 
     _stopWatch.Stop(); 
     _stopWatch.Reset(); 
    } 
} 
} 

よりよい解決策がイマイチ場合..

  • は2つの機能の間でマージする方法はあります:


    これは私がこれまでにやったことありますか? (1つは戻り値を含み、2つ目はvoid関数を得る)

  • タプルよりも明瞭な何かを返す方法はありますか? ..私はよく見るdoesntのも作られたクラスを呼び出す

    var tuple = await _timeMeasurer.Start(async() => await function(param1, param2)); 
    

    EDITを:私はそれが一種の厄介


編集に対処するために見つける私はこのアイデアを放棄することを決めました。そのあまりにも乱雑です。最後に、StopWatchを使用して

答えて

0

あなたの最初のポイントとして、それ以上の機能を組み合わせることはできませんが、多くの論理を組み合わせるだけではありません。

2番目の点については、結果を保持するために2つのカスタムクラスを作成します。誰かが返されたタスクのいくつかのプロパティを見たいと思った場合の結果だけでなく、空想を得て継承を行い、タスクオブジェクト全体を返すことができます。

最後に、関数をインスタンスにする必要はありません。クラス全体を静的にすることができます。

ここに私が提案した変更がある例があります。ここで

public class TimeMeasurerResult 
{ 
    protected readonly Task _task; 
    private readonly TimeSpan _duration; 

    public TimeMeasurerResult(Task task, TimeSpan duration) 
    { 
     _task = task; 
     _duration = duration; 
    } 

    public Task Task {get { return _task;}} 
    public TimeSpan Duration {get {return _duration;}} 
} 

public class TimeMeasurerResult<T> : TimeMeasurerResult 
{  
    public TimeMeasurerResult(Task<T> task, TimeSpan duration) 
     :base(task, duration) 
    { 
    } 

    public T Result {get { return ((Task<T>)_task).Result;}} 
} 

public static class TimeMeasurer 
{  
    public static async Task<TimeMeasurerResult<TReturn>> Start<TReturn>(Func<Task<TReturn>> function) 
    { 
     var stopWatch = Stopwatch.StartNew(); 
     var task = function(); 
     await task; 
     var took = stopWatch.Elapsed; 

     return new TimeMeasurerResult<TReturn>(task, took); 
    } 

    public static async Task<TimeMeasurerResult> Start(Func<Task> function) 
    { 
     var stopWatch = Stopwatch.StartNew(); 
     var task = function(); 
     await task; 
     var took = stopWatch.Elapsed; 

     return new TimeMeasurerResult(task, took); 
    }  
} 

using itの一例であり、私は唯一のvar results = await TimeMeasurer.Start(() => Function(a,b));ないvar results = await TimeMeasurer.Start(async() => await Function(a,b));

public class Program 
{ 
    public static void Main() 
    { 
     AsyncMain().Wait(); 
    } 

    public static async Task AsyncMain() 
    { 
     int a = 500; 
     int b = 10; 
     var results = await TimeMeasurer.Start(() => Function(a,b)); 
     Console.WriteLine("Waited: {0}", results.Duration.TotalSeconds); 
     Console.WriteLine("Result: {0}", results.Result); 
    } 

    public static async Task<int> Function(int a, int b) 
    { 
     var total = a + b; 
     await Task.Delay(total); 
     return total; 
    } 
} 
+0

を行うために必要なことに注意していいですね!それ以上の解決策があれば、私はそれらを聞きたいと思う。 – Mei

関連する問題