Visual Studioでは、Re-Sharperはforループをlinq式に変換することを推奨し続けていますが、これにはどのような理由がありますか?
どちらが速いですか?
Resharperがlinq変換を提案するループの例を次に示します。
foreach (XmlNode legendEntryNode in _legendEntryNodes)
{
var xmlElement = legendEntryNode["FeatureType"];
if (xmlElement == null || !xmlElement.InnerText.Equals(featuretype)) continue;
var xmlNodeList = legendEntryNode.SelectNodes("Themes/Theme");
if (xmlNodeList != null)
foreach (XmlNode themeNode in xmlNodeList)
{
var element = themeNode["Value"];
if (element == null || !element.InnerText.Equals(v)) continue;
var xmlElement1 = themeNode["Icon"];
if (xmlElement1 != null)
{
string iconname = "<ms:ICON>" + xmlElement1.InnerText + "</ms:ICON>";
var element1 = themeNode["Highlight"];
if (element1 != null)
{
string highlightname = "<ms:HIGHLIGHT>" + element1.InnerText + "</ms:HIGHLIGHT>";
gml = gml.Insert(c, iconname + highlightname);
c += (iconname.Length + highlightname.Length);
}
}
break;
}
}
そして、この簡単な例:
for (int i = 0; i < getPointsRequest.Attribs.Length; i++)
{
string attribName = getPointsRequest.Attribs[i].AttributeName;
if (!String.IsNullOrEmpty(attribName))
{
sqlQuery += "<ms:" + attribName + ">||\"" + attribName + "\"||</ms:" + attribName + ">";
}
}
コードの大部分では速度が無関係であることがよくあります。コードを最も単純なの方法で記述し、それを測定して十分に速いであることを確認する必要があります。
Forループが本当にクエリを実行しているだけの場合、LINQは絶対により読みやすいコードを作成するための優れた方法です。それは普遍的に適用できるわけではありませんが、少なくとも覚えておいてください頻繁にすべきことです。
多くの場合、forループをクエリに変換して遅延評価し、クエリによって返された各値に対して何らかのアクションを実行するforeachループを作成できます。これにより、2つの側面を分離し、コードを読むときに一度に1つずつ集中できるようになります。ただし、LINQクエリを保持することは重要ですasクエリ内で副作用を使用するのではなく、機能的なアプローチを持つように設計されていますが、実際には副作用とうまく混ざりません。
具体的な例があれば、LINQを使用するように変換するのに意味のあるループとそうでないループについて、より多くの意見を述べることができます。
そのようなパフォーマンスの向上はありませんが、いくつかの利点があります
詳細については、以下を参照してください。
これがお役に立てば幸いです。
速度に違いはない可能性がありますが、Linqを使用するとコードが簡潔になることがよくあります。これは、Linq式に変換するためのR#の提案を常に受け入れる必要があるということではありません。複雑であるが理解できるforeachループが、有効であるが簡単には理解できないLinq式に変換されることがあります。
たまに改宗しないのには理由があると思います。 ReSharperがLINQ式(戻る)をforループに変換するためのリファクタリングを提供しないことはおそらくあまり称賛に値しません。ループを式に変換した後、ループ内にさらにいくつかのアクション(多くの場合デバッグアクション)を入れたいと思ったことが何度かありました。手作業で元に戻す必要があります。
正当な理由なしにforループを変換しないように警告します。多くの場合、それは実際には読みやすさを改善せず、それを行う他の強力な理由はありません(他の人が正しく指摘しているように、ほとんどのループは速度が重要ではありません)。
一部のforループは、ループのアクションを一口サイズの断片に視覚的に分解するため、LINQの同等のものよりも読みやすいと思います。小さなループ(3行または4行)が1行の式にすることで最も改善される傾向があると思います。
[申し訳ありませんが、この投稿はほとんど意見ですが、読みやすさは少し主観的な主題です。トローリングなし!]
一般に、ReSharperの提案は単なる提案であり、警告はありません。したがって、LINQまたはforeachのどちらに進むかを決めるのは、あなた次第です。
「Use'var '」という提案でも同じ問題が発生します。読者がステートメントをよりよく読むことができると思う場合にのみ、その提案をクリックします。
コードを書くときの読みやすさは私の最優先事項の1つです。
こんにちはLinqは実際に内部でforループを呼び出しています。 Linq式は、一般的に読みやすく、保守しやすいということになると思います。パフォーマンスが本当に心配な場合は、2つの間に良い比較があります: http://geekswithblogs.net/BlackRabbitCoder/archive/2010/04/23/c-linq-vs-foreach---round- 1.aspx
他の人への参照として、Resharperによって提案されたforループとforループの例を次に示します。
for (int x = 0; x < grid.Length; x++)
{
var intCount = grid[x].Select((a, b) => new {Value = a, Index = b})
.GroupBy(y => y.Value)
.Where(y => y.Count() > 1).Select(item => item.Key).ToArray();
if (intCount.Count() > 1)
return false;
}
このコードを説明するために、このforループは配列上のすべての重複を取得します。すべての重複を取得したら、アイテムの数が1より大きいかどうかを確認し、falseを返します。
これは、LINQで推奨されるforループです。
return grid.Select(t => t.Select((a, b) => new {Value = a, Index = b}).
GroupBy(y => y.Value).Where(y => y.Count() > 1).
Select(item => item.Key).ToArray()).All(intCount => intCount.Count() <= 1);
パフォーマンスの向上はないかもしれませんが、例からわかるように、LINQクエリはよりクリーンで読みやすく、行数が少なくなっています(この場合、コードは1行だけで、ここに貼り付けた後で調整しました)。デバッグも簡単です。