たまたま、5年間積極的にコーディングすることができませんでした。ですから、コードに入り、仲間を混乱させるあらゆる機会は、昔を揺るがし、「お尻のベリー」(別名、お尻の千枚通し)がまだあることを確認する機会として、喜びで認識されます。はい。この記事はチュートリアルであり、「なんてクールなのか」というシリーズではなく、「ああ、同僚に問題を引き起こすテクノロジーの使用を簡単な例で示すのに良いオプションだ」というシリーズから、すぐに予約します。そのようなソリューションは、C#開発者の武器庫に含まれるべきであると私は深く信じています。
ちょうど今、私は係数の一定の取得が積極的に関与する多段階近似プロセスを含むコードをレビューしました(係数は値の範囲に対して選択されます。誰かが詳細を気にするなら、私たちは大気中の独自のプロペラなしで、オギバル型の体の動きをモデル化することについて話します。体の現在の速度に応じてIGallaCSFテーブルから取得されます(速度の範囲は特定のCSFに対応し、テーブル内の約300要素)。
プロセスはマルチステップであり、検索操作は頻繁に実行され、子供たちの開発者は素晴らしく、バイナリ検索よりもさらに進んで、値の範囲の整数キーの計算を実装し、このキーの係数を取得しました。Dictionary
そして、アジャイルチーム、そして私、醜い、SixSigmaと私は本当にすべてを数字で見るのが好きです-そして、彼らは説得力を持って選択されたソリューションの有効性を示しました。1000ポイントの近似からの1つの計算の場合、コストは次のとおりです。
テーブル内の
線形検索-0.6msチェーンによる線形検索if-return-0.1ms
半分の分割
による検索-0.08ms辞書による検索-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.: , , . - , , , , , . , , , . .