Lorsque le programmeur n'a rien Ă  faire ou Ă  optimiser le code Ă  l'aide de Linq.

Il se trouve que je n'ai pas pu coder activement pendant cinq ans. Ainsi, chaque chance d'entrer dans le code et de jouer avec vos camarades est perçue avec joie, comme une opportunité de secouer l'ancien temps et de s'assurer qu'il y a encore des "baies dans les fesses" (alias un poinçon dans le cul). Oui, et je ferai une réservation tout de suite que l'article est plus un tutoriel, pas de la série "look wow how cool I can", mais de la série "oh, quelle bonne option pour montrer avec un exemple simple l'utilisation d'une technologie qui cause des difficultés à certains collègues." Je suis profondément convaincu que de telles solutions devraient être incluses dans l'arsenal de tout développeur C #.





Je viens de passer en revue le code, qui comprend un processus d'approximation en plusieurs Ă©tapes, dans lequel l'obtention constante du coefficient est activement impliquĂ©e (le coefficient est sĂ©lectionnĂ© pour une plage de valeurs. Si quelqu'un se soucie des dĂ©tails, nous parlons de modĂ©liser le mouvement d'un corps de forme ogivale, sans sa propre hĂ©lice, dans l'atmosphère. va du tableau IGalla CSF en fonction de la vitesse actuelle du corps (la plage de vitesses correspond Ă  un CSF spĂ©cifique, environ 300 Ă©lĂ©ments dans le tableau). 





Le processus est en plusieurs étapes, l'opération de recherche est souvent effectuée et les enfants-développeurs ont été formidables, sont allés encore plus loin que la recherche binaire, ont mis en œuvre le calcul d'une clé entière pour une plage de valeurs et obtenu un coefficient pour cette clé grâce à Dictionary



Et puisque l'équipe Agile, et moi, moche, aussi SixSigma et J'aime vraiment tout voir en chiffres - alors les gars ont montré de manière convaincante l'efficacité de la solution choisie. Pour 1 calcul sur 1000 points d'approximation, les coûts sont:





Recherche linéaire dans le tableau - 0,6ms

Recherche linéaire par chaîne if-return - 0,1ms

Recherche par division en deux - 0,08ms

Recherche par dictionnaire - 0,018ms





, “ ”. - (, , , ). 





, “” , “ ” - 6 ( ). - 4 . 





“ ”, - -, data-driven , 20 . - .NET “ ”. if , Linq ? , . , , “” . 





- . . - - . - if, , - if, . 





if, , . - range (), , (value), (v) .   , , Linq - , if if.





If (v >= from && v < to) return value;
      
      



public Expression CreateSimpleIf(double from, double to, 
                      double value, 
                      Expression v, LabelTarget returnTarget)
{
    var returnStmt = Expression.Return(
      returnTarget, 
      Expression.Constant(value));
    var ifCondition = Expression.AndAlso(
        Expression.GreaterThanOrEqual(v, Expression.Constant(from)), 
        Expression.LessThan(v, Expression.Constant(to)));
    return Expression.IfThen(ifCondition, returnStmt);
}
      
      







. 1 2 , , -,   , . 





, . 









if (v >= mid.from && v < mid.to) 
   return mid.value 
if (v < mid.from)    
    return search in (0...mid-1) 
else    
    return search in (mid + 1...length - 1);
      
      



Span



/ / “ ”. 





public Expression CreateSpanExpression(Span<Coefficient> span, 
          Expression v, 
          LabelTarget returnTarget)
{
    if (span.Length == 1)
        return CreateSimpleIf(span[0].RangeFrom, 
                   span[0].RangeTo, 
                   span[0].Value, 
                   v, returnTarget);
    else if (span.Length == 2)
    {
        Expression[] ifs = new Expression[2];
        ifs[0] = CreateSimpleIf(span[0].RangeFrom, 
                   span[0].RangeTo, 
                   span[0].Value, 
                   v, returnTarget);
        ifs[1] = CreateSimpleIf(span[1].RangeFrom, 
                   span[1].RangeTo, 
                   span[1].Value, 
                   v, returnTarget);
        return Expression.Block(ifs);
    }
    else
    {
        int mid = span.Length / 2;
        Expression[] blocks = new Expression[2];
        blocks[0] = CreateSimpleIf(span[mid].RangeFrom, 
                       span[mid].RangeTo, 
                       span[mid].Value, 
                       v, returnTarget);

        var leftSide = 
          CreateSpanExpression(span.Slice(0, mid), 
                               v, returnTarget);
        var rightSide = 
          CreateSpanExpression(span.Slice(mid + 1, 
                               span.Length - mid - 1), 
                               v, returnTarget);

        Expression condition = 
          Expression.LessThan(v, 
                              Expression.Constant(span[mid].RangeFrom));
        blocks[1] = Expression.IfThenElse(condition, leftSide, rightSide);
        return Expression.Block(blocks);
     }
} 
      
      



- . , , lambda- . 





public Func<double, double> CreateBTReeExpression()	
{
    var value = Expression.Parameter(typeof(double), "value");
    var returnTarget = Expression.Label(typeof(double));

    var ifs = CreateSpanExpression(mCoefficients.ToArray(), 
                                   value, returnTarget);
    var body = Expression.Block(typeof(double), 
                 new Expression[] 
                 { 
                   ifs, 
                   Expression.Label(returnTarget, 
                     Expression.Constant(0.0))
                 });

    var expression = Expression.Lambda(typeof(Func<double, double>), 
                       body, 
                       new ParameterExpression[] { value });
    var functionDelegate = expression.Compile();
    return (Func<double, double>) functionDelegate;        
}
      
      







, , ? 0.012ms, 1.5 Dictionary



. . 





, , , “” - , , , “” . , - , .  





, , , “ IDE” , . 





, , , , - , , , , ( , ). “, ”.  





, – , , . silver bullet .





P.S.: , , . - , , , , , . , , , . .








All Articles