以下代碼是我試圖優化的代碼的簡化版本。在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的簽名。GetCharacters方法調用代價昂貴,但是線程安全。 SplitItOut方法的輸入可以包含100,000個以上的條目,並且對GetCharacters()方法的單個調用可能需要大約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'?我敢打賭,這就是爲什麼你的算法很慢。 – 2012-01-27 02:43:29
這只是一個示例代碼。 Thread.Sleep(5000)只是爲了表明實際的GetCharacters()方法調用起來很昂貴。 – Snakebyte 2012-01-27 02:47:02
什麼是它的約束?中央處理器?磁盤?網絡? – 2012-01-27 02:47:50