Wenn der Programmierer nichts zu tun hat oder den Code mit Linq.Expression optimiert

So kam es, dass ich seit fünf Jahren nicht mehr aktiv codieren konnte. Jede Chance, in den Code einzusteigen und sich dort mit Ihren Kameraden herumzuschlagen, wird mit Freude wahrgenommen, als Gelegenheit, die alten Zeiten zu erschüttern und sicherzustellen, dass immer noch "Beeren im Gesäß" (auch bekannt als Ahle im Arsch) sind. Ja, und ich werde sofort reservieren, dass der Artikel eher ein Tutorial ist, nicht aus der Serie "Schau, wie cool ich kann", sondern aus der Serie "Oh, was für eine gute Option, um anhand eines einfachen Beispiels den Einsatz einer Technologie zu zeigen, die einigen Kollegen Schwierigkeiten bereitet." Ich bin der festen Überzeugung, dass solche Lösungen in das Arsenal eines jeden C # -Entwicklers aufgenommen werden sollten.





Gerade habe ich den Code überprüft, der einen mehrstufigen Approximationsprozess umfasst, bei dem das konstante Erhalten des Koeffizienten aktiv beteiligt ist (Der Koeffizient wird für einen Wertebereich ausgewählt. Wenn sich jemand um die Details kümmert, sprechen wir über die Modellierung der Bewegung eines ogivalförmigen Körpers ohne eigenen Propeller in der Atmosphäre. geht von der IGalla CSF-Tabelle entsprechend der aktuellen Geschwindigkeit des Körpers aus (der Geschwindigkeitsbereich entspricht einem bestimmten CSF, etwa 300 Elemente in der Tabelle). 





Der Prozess ist mehrstufig, die Suchoperation wird häufig ausgeführt, und die Kinderentwickler waren großartig, gingen sogar noch weiter als die binäre Suche, implementierten die Berechnung eines Ganzzahlschlüssels für einen Wertebereich und erhielten einen Koeffizienten für diesen Schlüssel durch Dictionary



Und da das Agile-Team und ich, hässlich, auch SixSigma und Ich mag es wirklich, alles in Zahlen zu sehen - dann haben die Jungs überzeugend die Effektivität der gewählten Lösung gezeigt. Für 1 Berechnung aus 1000 Näherungspunkten betragen die Kosten:





Lineare Suche in der Tabelle - 0,6 ms

Lineare Suche mit If-Return-Kette - 0,1

ms

Suche nach Halbierung - 0,08 ms Suche nach Wörterbuch - 0,018 ms





, “ ”. - (, , , ). 





, “” , “ ” - 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