Acontece que não fui capaz de codificar ativamente por cinco anos. Portanto, toda chance de entrar no código e mexer com seus camaradas lá é percebida com alegria, como uma oportunidade de sacudir os velhos tempos e ter certeza de que ainda há "frutinhas nas nádegas" (também conhecido como um furador no traseiro). Sim, e farei uma ressalva já que o artigo é mais um tutorial, não da série "olha que legal eu consigo", mas da série "ah, que boa opção mostrar com um simples exemplo o uso de uma tecnologia que causa dificuldades para alguns colegas". É minha profunda convicção que tais soluções devem ser incluídas no arsenal de qualquer desenvolvedor C #.
Acabei de revisar o código, que inclui um processo de aproximação de várias etapas, no qual a obtenção da constante do coeficiente está ativamente envolvida (O coeficiente é selecionado para uma faixa de valores. vai da tabela IGalla CSF de acordo com a velocidade atual do corpo (a faixa de velocidades corresponde a um CSF específico, cerca de 300 elementos na tabela).
O processo é multi-etapas, a operação de busca é realizada frequentemente, e os kids-developers foram ótimos, foram ainda mais longe do que a busca binária, implementaram o cálculo de uma chave inteira para uma gama de valores e obtendo um coeficiente para esta chave através de Dictionary
E desde a equipe Agile, e eu, feio, também SixSigma e Gosto muito de ver tudo em números - então os caras mostraram de forma convincente a eficácia da solução escolhida. Para 1 cálculo de 1000 pontos de aproximação, os custos são:
Pesquisa linear na tabela - 0,6 ms
Pesquisa linear com cadeia de retorno
if - 0,1 ms
Pesquisa por divisão ao meio - 0,08 ms Pesquisa por dicionário - 0,018 ms
Acertou minha mesa no momento em que o projeto engatinhava para o palco “e agora estamos fazendo os mesmos cálculos no microcontrolador”. Acontece que a transferência do dicionário não foi muito boa (sim, eles poderiam ter pensado com antecedência, mas eles enfrentaram microcontroladores pela primeira vez, então vamos perdoá-los por essa omissão).
Graças à equipe, eles já contaram os números para “pensar”, e percebi que o ganho de “código limpo” versus busca na estrutura de dados é de 6 vezes (primeiras linhas). E salvando o dicionário contra a redução pela metade - um pouco mais de 4 vezes.
“ ”, - -, 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.: , , . - , , , , , . , , , . .