web-dev-qa-db-ja.com

単純なLINQクエリを並列で実行する

私はまだLINQとPLINQにまだ慣れていません。多くの場合、私は通常ループとList.BinarySearchだけを使用しますが、可能な限りその考え方から抜け出そうとしています。

public class Staff
{
  // ...
  public bool Matches(string searchString)
  {
    // ...
  }
}

「通常の」LINQを使用している-申し訳ありませんが、この用語に慣れていません-次のことができます。

var matchedStaff = from s
                     in allStaff
                  where s.Matches(searchString)
                 select s;

しかし、私はこれを並行して行いたいです:

var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString));

matchedStaffのタイプを確認すると、それはboolsのリストです。これは私が望んでいるものではありません。

まず、ここで何が問題になっていますか。次に、このクエリからList<Staff>を返すにはどうすればよいですか。

public List<Staff> Search(string searchString)
{
  return allStaff.AsParallel().Select(/* something */).AsEnumerable();
}

IEnumerable<type>ではなくList<type>を返します。

19
user1002358

最初の質問の場合、SelectWhereに置き換えるだけです。

_var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString));
_

Selectは射影演算子であり、フィルタリング演算子ではないため、入力シーケンスから返されたブール値へのすべてのStaffオブジェクトの射影に対応する_IEnumerable<bool>_を取得しています。 Matchesメソッド呼び出し。

「ラムダ構文」を使用する場合とは異なり、selectキーワードが必須である「クエリ構文」に慣れているように見えるので、selectをまったく使用しないと直感に反することになると思います。または「流暢な構文」...名前は何でも)、しかしそれはそれがそうである方法です;)

Selectなどの射影演算子は、シーケンスからの要素を入力として受け取り、この要素を何らかの方法で別のタイプの要素に変換/投影します(ここではboolに投影しています)タイプ)。一方、_Whereなどのフィルタリング演算子は、シーケンスから要素を入力として受け取り、その要素を出力シーケンスにそのまま出力するか、または要素をまったく出力しません。述語に。

2番目の質問と同様、AsEnumerableIEnumerableを返します。これは、その名前が示すとおりです;)_List<Staff>_を取得する場合は、ToList()(名前が;)を示すため):

_return allStaff.AsParallel().Select(/* something */).ToList();
_

お役に立てれば。

32
darkey

並列処理を実現するために通常のLINQ構文を放棄する必要はありません。元のクエリを書き換えることができます。

_var matchedStaff = from s in allStaff
    where s.Matches(searchString)
    select s;
_

並列LINQ( “ PLINQ” )バージョンは次のようになります。

_var matchedStaff = from s in allStaff.AsParallel()
    where s.Matches(searchString)
    select s;
_

boolsがどこから来ているのかを理解するには、次のように記述します。

_var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString));
_

これは、次のクエリ構文と同等です。

_var matchedStaff = from s in allStaff.AsParallel() select s.Matches(searchString);
_

darkeyで述べたように 、クエリ構文の代わりにC#構文を使用する場合は、 Where() を使用する必要があります。

_var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString));
_
8
binki