私はメッシュレンダリングマネージャーを作成していて、同じシェーダーを使用するすべてのメッシュをグループ化してから、そのシェーダーパスでこれらをレンダリングすることをお勧めします。
現在foreach
ループを使用していますが、LINQを使用するとパフォーマンスが向上するかどうか疑問に思いますか?
私はメッシュレンダリングマネージャーを作成していて、同じシェーダーを使用するすべてのメッシュをグループ化してから、そのシェーダーパスでこれらをレンダリングすることをお勧めします。
現在foreach
ループを使用していますが、LINQを使用するとパフォーマンスが向上するかどうか疑問に思いますか?
回答:
なぜLINQの方が速いのですか?また、内部でループを使用します。
ほとんどの場合、オーバーヘッドが発生するため、LINQは少し遅くなります。パフォーマンスを重視する場合は、LINQを使用しないでください。LINQを使用するのは、短くて読みやすく保守しやすいコードが必要だからです。
LINQ-to-Objectsは一般に、いくつかの限界的なオーバーヘッド(複数の反復子など)を追加します。それはまだループを行う必要があり、およびデリゲート呼び出すを持ち、かつ一般的に、これは事実上検出できないだろうほとんどのコードで撮影した変数などで取得するためのいくつかの余分な間接参照を行う必要があります、そしてより多くのコードを理解するために単純で与えられます。
LINQ-to-SQLのような他のLINQプロバイダーでは、クエリはサーバーでフィルタリングできるため、フラットよりもはるかに優れているはずですが、とにかくforeach
ブランケットを実行しなかった可能性が高いので、必ずしも公平ではありません。比較。"select * from foo"
PLINQについて 並列処理により経過時間が短縮される可能性がありますが、スレッド管理のオーバーヘッドなどにより、通常、合計CPU時間は少し増加します。
List<Foo>
; 代わりに、foreach
これらのコレクションでブロックを使用する必要があります。foreach
これらのコンテキストで使用することをお勧めします。私の懸念:パフォーマンスの問題を検出したforeach
場合にのみ、LINQクエリを置き換える必要がありますか?今後は、foreach
最初のものを検討します。
LINQはforeach
ループを介して使用する方が良いと思います。ループを使用すると、コードがはるかに簡潔でわかりやすくなるからです。ただし、LINQはよりも低速ですforeach
。詳細については、「LINQ vs FOREACH vs FORループパフォーマンス」を参照してください。
現在、LINQは低速ですが、ある時点で高速になる可能性があります。LINQの良い点は、それがどのように機能するかを気にする必要がないことです。信じられないほど高速な新しい方法が考えられた場合、Microsoftの担当者はそれを実装しなくても実装でき、コードははるかに高速になります。
さらに重要なのは、LINQの方がはるかに読みやすいことです。それで十分だろう。
for
ループはforeach
。よりも速いことに注意してください。したがって、元の投稿では、レンダラーなどの重要なコンポーネントのパフォーマンスが心配な場合は、for
ループを使用します。
マルチコアに並列LINQを使用すると、パフォーマンスが向上する場合があります。Parallel LINQ(PLINQ)(MSDN)を参照してください。
この質問に興味があったので、今テストをしました。Intel(R)Core(TM)i3-2328M CPU @ 2.20GHz、2200 Mhz、2コアで.NET Framework 4.5.2を使用し、Microsoft Windows 7 Ultimateを実行する8GB RAMを搭載。
LINQは各ループよりも高速であるように見えます。これが私が得た結果です:
Exists = True
Time = 174
Exists = True
Time = 149
このコードをコピーしてコンソールアプリに貼り付け、テストすることもできれば興味深いでしょう。オブジェクト(従業員)でテストする前に、整数で同じテストを試しました。LINQも高速でした。
public class Program
{
public class Employee
{
public int id;
public string name;
public string lastname;
public DateTime dateOfBirth;
public Employee(int id,string name,string lastname,DateTime dateOfBirth)
{
this.id = id;
this.name = name;
this.lastname = lastname;
this.dateOfBirth = dateOfBirth;
}
}
public static void Main() => StartObjTest();
#region object test
public static void StartObjTest()
{
List<Employee> items = new List<Employee>();
for (int i = 0; i < 10000000; i++)
{
items.Add(new Employee(i,"name" + i,"lastname" + i,DateTime.Today));
}
Test3(items, items.Count-100);
Test4(items, items.Count - 100);
Console.Read();
}
public static void Test3(List<Employee> items, int idToCheck)
{
Stopwatch s = new Stopwatch();
s.Start();
bool exists = false;
foreach (var item in items)
{
if (item.id == idToCheck)
{
exists = true;
break;
}
}
Console.WriteLine("Exists=" + exists);
Console.WriteLine("Time=" + s.ElapsedMilliseconds);
}
public static void Test4(List<Employee> items, int idToCheck)
{
Stopwatch s = new Stopwatch();
s.Start();
bool exists = items.Exists(e => e.id == idToCheck);
Console.WriteLine("Exists=" + exists);
Console.WriteLine("Time=" + s.ElapsedMilliseconds);
}
#endregion
#region int test
public static void StartIntTest()
{
List<int> items = new List<int>();
for (int i = 0; i < 10000000; i++)
{
items.Add(i);
}
Test1(items, -100);
Test2(items, -100);
Console.Read();
}
public static void Test1(List<int> items,int itemToCheck)
{
Stopwatch s = new Stopwatch();
s.Start();
bool exists = false;
foreach (var item in items)
{
if (item == itemToCheck)
{
exists = true;
break;
}
}
Console.WriteLine("Exists=" + exists);
Console.WriteLine("Time=" + s.ElapsedMilliseconds);
}
public static void Test2(List<int> items, int itemToCheck)
{
Stopwatch s = new Stopwatch();
s.Start();
bool exists = items.Contains(itemToCheck);
Console.WriteLine("Exists=" + exists);
Console.WriteLine("Time=" + s.ElapsedMilliseconds);
}
#endregion
}
Exists=True Time=184 Exists=True Time=135
ことは、Apacheゲーミングノートパソコン(10勝、C#7.3)にあります。コンパイルされ、デバッグモードで実行されました。私がテストを逆にすると私は得るExists=True Time=158 Exists=True Time=194
。Linqはより最適化されているようです。
これは実際にはかなり複雑な質問です。Linqを使用すると、特定の処理を非常に簡単に行うことができます。それらを自分で実装すると、つまずく可能性があります(たとえば、linq .Except())。これは特にPLinqに適用され、特にPLinqによって実装される並列集約に適用されます。
一般に、同じコードの場合、デリゲート呼び出しのオーバーヘッドのため、linqは遅くなります。
ただし、大量のデータ配列を処理し、要素に比較的単純な計算を適用する場合は、次の場合にパフォーマンスが大幅に向上します。
forループを使用して、各要素にアクセスします(foreachまたはlinqとは対照的です)。