将时间执行计算为单独的类,其中函数是可变的

问题描述 投票:0回答:3

让我们进行以下二元搜索功能:

public static bool BinarySearching(int[] array, int searchValue)
{
    Array.Sort(array);
    double p = 0;
    double q = 0;
    int r = array.Length - 1;

    while (p <= r)
    {
        q = Math.Floor((p + r) / 2);

        if (array[(int)q] == searchValue)
        {
            return true;
        }

        else if (array[(int)q] != searchValue && array[(int)q] > searchValue)
        {
            r = (int)(q - 1);
        }

        else if (array[(int)q] != searchValue && array[(int)q] < searchValue)
        {
            p = (int)(q + 1);
        }
    }

    return false;
}

}

如果我们想测量它的执行时间,我们会做类似的事情

var watch = System.Diagnostics.Stopwatch.StartNew();
BinarySearching(int[] array, int searchValue);
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;

但是,通过单独的函数测量变量是否更美观,这样变量才能自行计算?例如,在伪代码中它是

public static string ComplexityCounter(bool algorithm(int[] array, int searchValue))
{
    var watch = System.Diagnostics.Stopwatch.StartNew();
    algorithm(int[] array, int searchValue);
    watch.Stop();
    var elapsedMs = watch.ElapsedMilliseconds;
    string result = elapsedMs.ToString();
    return result;
}

并且,确定它在C#方面不起作用,你能帮我修改它还是提出你自己的尝试?最有趣的是为所有算法找到这样的结构,而不管它产生的变量类型如何。

c# algorithm time-complexity
3个回答
0
投票

我建议你接受一个Action,它更通用,你可以将它用于更多的功能。然后,您可以使用lamda表达式调用它。例:

    private static long MeasureDuration(Action algorithm)
    {
        var watch = System.Diagnostics.Stopwatch.StartNew();

        algorithm.Invoke();

        watch.Stop();

        return watch.ElapsedMilliseconds;
    }

我使用.Invoke(),它让人们更容易理解这是一个被调用的动作。

并称之为:

  bool found;
  var result = MeasureDuration(() => found = BinarySearching(myArray, mySearchValue));

0
投票

您可以将Func<bool>作为参数传递,如下所示:

public static TimeSpan Measure(Func<int[], int, bool> method, int[] arg1, int arg2)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    var result = method.Invoke(arg1, arg2);
    stopwatch.Stop();
    return stopwatch.Elapsed;
}

然后你可以像这样调用它:

var timeTaken = Measure(MethodToMeasure, new [] {1, 2, 3}, 1);

0
投票

假设你不想像在基于Action的回答中那样丢弃算法的结果,那么实现它的最通用方法可能是在返回类型中使方法通用,并将算法的输入参数绑定在lambda中表达式,因此具有Func<T>类型。我假设您可以使用新的C#7元组语法

private static (T, long) GetResultAndDuration<T>(Func<T> algorithm)
{
   var watch = System.Diagnostics.Stopwatch.StartNew();

   T result = algorithm();

   watch.Stop();

   return (result, watch.ElapsedMilliseconds);
}

您可以按如下方式调用它:

(var result, var duration) = GetResultAndDuration(() => MyCoolAlgorithm(42, "some param"));
© www.soinside.com 2019 - 2024. All rights reserved.