【问题标题】:Generic function to test the performance of any delegate用于测试任何委托的性能的通用函数
【发布时间】:2012-11-20 18:14:59
【问题描述】:

在测试不同方法实现的相对性能时,我发现自己重写了类似的函数。

private static long Measure(
    int iterations,
    Func<string, string> func,
    string someParameter)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    for (var i = 0; i < iterations; i++)
    {
        func(someParameter);
    }

    stopwatch.Stop();
    return stopwatch.ElapsedTicks;
}

与其为我测试的每个方法签名重写此函数,是否可以编写一个通用实现来测试任何 delagate 的性能?类似于

    private static long Measure(
    int iterations,
    Delegate func,
    params object[] parameters)
{
    ...
}

    private static long Measure<TDelegate>(
    int iterations,
    TDelegate func,
    params object[] parameters)
{
    if (!typeof(TDelegate).IsSubclassOf(typeof(Delegate)))
    {
        throw new ArgumentException("Not a delegate", "func");
    }

    ...
}

如果我能做到这一点,在执行迭代之前CompileExpression&lt;TDelegate&gt; 是否有意义?

【问题讨论】:

    标签: c# generics reflection lambda


    【解决方案1】:

    为什么不使用 Action,您可以在 lambda 中设置参数。

    private static long Measure(int iterations, Action action)
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        for (var i = 0; i < iterations; i++)
        {
            action();
        }
    
        stopwatch.Stop();
        return stopwatch.ElapsedTicks;
    }
    

    那你就这样称呼它

    Measure(100, () => MyMethod(arg1,arg2,...));
    

    【讨论】:

    • 谢谢你的回答帮助我理解了。
    • +1 为了消除 JIT 问题,我会在启动计时器之前调用一次 action();
    • 这里的缺点是,用于设计调用的 lamda 函数成为测试的一部分。但是,我认为没有任何替代方法可以克服这一点。总会涉及到管道元素。
    【解决方案2】:

    你可以只使用匿名函数来传递参数:

    var p1 = ..
    var p2 = ..
    var p3 = ..
    var p4 = ..
    var p5 = ..
    Measure(1000, (x) => MyTestFunc(p1, p2, p3, p4, p5), str);
    

    【讨论】:

    • 那么Measure的第二个参数是什么类型?
    • 假设MyTestFunc的返回类型为stringxstring,则(x) =&gt; MyTestFunc(p1, p2, p3, p4, p5)的类型为Func&lt;string, string&gt;。尽管在这种情况下,输入string 参数和返回值实际上都没有在任何地方使用——它们只是为了满足Measure 的参数类型。如果您不需要它们,请按照@juharr 的建议使用Action
    • 我明白你现在在说什么
    • 这里的缺点是,用于设计调用的 lamda 函数成为测试的一部分。但是,我认为没有任何替代方法可以克服这一点。
    • @Jodrell:是的。但是,与所有时间测试一样,您正在测试相对性能。如果您使用相同的测试工具测试方法 1 和方法 2,您应该能够准确地确定哪种方法“更快”。如果您真的要对每次需要几毫秒的方法进行 100,000 次迭代(其中 lamdba 可能会对时间产生明显影响),我会更快地检查您是否陷入过早优化的危险。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 2012-11-06
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多