65.9K
CodeProject 正在变化。 阅读更多。
Home

基于性能的动态方法选择

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.29/5 (5投票s)

2008年12月14日

CPOL

2分钟阅读

viewsIcon

24111

downloadIcon

69

一种模型,用于自动从具有相同功能的多个方法中选择性能最佳的方法。

AdaptiveMethodSelector

引言

我们经常发现有多种方法可以完成同一件事。即使我们创建了最复杂的方法来从源获取信息,我们仍然依赖于外部依赖项,例如数据库或网络延迟;或者硬盘或计算机故障等物理因素,这些因素是不确定的,并且使我们在微调这些系统时面临更多困难。在这种情况下,一个好的方法是拥有第二种或第三种替代方案,如果无法以通常的方式获取数据,我们可以尝试另一种方式,而这正是我们陷入永无止境的 try/catch 模式的原因。

方法

这里介绍的方法可以帮助您的系统主动识别一组方法中响应时间最短且没有异常的方法。其工作方式如下:基于一组具有相同签名、相同功能但不同实现的方法,该算法首先测试每个方法并测量响应时间;然后,它将选择响应时间最快且不抛出异常的方法;然后,如果方法响应时间超过阈值或抛出异常,它将重新评估所有方法并选择最快的方法。同时,它将不断调整以适应性能下降的情况。

示例

假设我们有两种不同的实现来连接两个字符串。第一种方法使用 String.Concat,第二种方法使用 StringBuilder。正如预期的那样,后者在运行示例时应该表现更好。

以下是您可以订阅自适应方法选择器中的所有方法的方式

private AdaptiveMethodSelector<string, ParamsMethods> _methodOptimizer;
private AdaptiveMethodSelector<string, ParamsMethods> MethodOptimizer
{
    get
    {
       if (_methodOptimizer != null)
         return _methodOptimizer;

       Collection<AdaptiveMethodSelector<string, ParamsMethods>.EvaluationMethodDelegate>
            functionsToEvaluate = new Collection<AdaptiveMethodSelector<string, 
                                  ParamsMethods>.EvaluationMethodDelegate>();
            functionsToEvaluate.Add(new AdaptiveMethodSelector<string, 
                                    ParamsMethods>.EvaluationMethodDelegate(Method1));
            functionsToEvaluate.Add(new AdaptiveMethodSelector<string, 
                                    ParamsMethods>.EvaluationMethodDelegate(Method2));

       _methodOptimizer = new AdaptiveMethodSelector<string, 
                                ParamsMethods>(functionsToEvaluate);
       return _methodOptimizer;
    }
}

AdaptiveMethodSelector 接受两种类型,第一种是方法的返回类型,第二种是传递的参数的类型。当需要将多个参数传递给方法时,您可以像在此示例中一样定义一个结构体;否则,您可以指示类型,例如 stringint 等。

示例中的方法签名如下

public string Method1(ParamsMethods parameters)
public string Method2(ParamsMethods parameters)

其中 ParamsMethods

public struct ParamsMethods
{
    public ParamsMethods(string param1, string param2)
    {
       Param1 = param1;
       Param2 = param2;
    }

    public string Param1;
    public string Param2;
}
© . All rights reserved.