次のコードは、私が最適化しようとしているコードの簡略化されたバージョンです。IEnumerable実装でタスク並列ライブラリを使用して速度向上を達成する
void Main()
{
var words = new List<string> {"abcd", "wxyz", "1234"};
foreach (var character in SplitItOut(words))
{
Console.WriteLine (character);
}
}
public IEnumerable<char> SplitItOut(IEnumerable<string> words)
{
foreach (string word in words)
{
var characters = GetCharacters(word);
foreach (char c in characters)
{
yield return c;
}
}
}
char[] GetCharacters(string word)
{
Thread.Sleep(5000);
return word.ToCharArray();
}
私は方法SplitItOut.The GetCharactersメソッドのシグネチャを変更することはできませんが呼び出すことが高価ですが、スレッドセーフです。 SplitItOutメソッドへの入力には100,000以上のエントリが含まれ、GetCharacters()メソッドへの1回の呼び出しには約200msかかる場合があります。私は無視することができる例外をスローすることもできます。結果の順序は関係ありません。
私の最初の試みでは、TPLを使用して次の実装に着手しました。これはかなり高速ですが、すべての単語を処理するまでブロックしています。
public IEnumerable<char> SplitItOut(IEnumerable<string> words)
{
Task<char[][]> tasks = Task<char[][]>.Factory.StartNew(() =>
{
ConcurrentBag<char[]> taskResults = new ConcurrentBag<char[]>();
Parallel.ForEach(words,
word =>
{
taskResults.Add(GetCharacters(word));
});
return taskResults.ToArray();
});
foreach (var wordResult in tasks.Result)
{
foreach (var c in wordResult)
{
yield return c;
}
}
}
私はこれよりもSplitItOut()メソッドの方が優れた実装を探しています。処理時間を短縮することが私の優先事項です。
を出力を置く
これは単なるサンプルコードです。 Thread.Sleep(5000)は、実際のGetCharacters()メソッドが呼び出すのに費用がかかることを示しています。 – Snakebyte
それは何に縛られていますか? CPU?ディスク?ネットワーク? –