以下是面試問題:使用LINQ生成素數
以下單線程生成並顯示前500個質數的列表。你會如何優化使用並行LINQ它同時仍保持它一個C#聲明:
MessageBox.Show(string.Join(",",
Enumerable.Range(2, (int)(500 * (Math.Log(500) + Math.Log(System.Math.Log(500)) - 0.5)))
.Where(x => Enumerable.Range(2, x - 2)
.All(y => x % y != 0))
.TakeWhile((n, index) => index < 500)));
我想介紹AsParallel()
以及ParallelEnumerable
到查詢,但沒有看到多核機器的任何實實在在的好處。查詢仍然使用一個CPU核心,而其他核心則享受閒暇時間。有人可以提出一種改進措施,可以平均分配所有內核的負載,從而縮短執行時間嗎?
對於發燒友:下面的公式返回一個上限這是保證,如果你選中了這個數字要大於N素數,也就是說,您將會確信求n素數小於它:
UpperBound = N * (Log(N) + Log(Log(N)) - 0.5) //Log is natural log
見http://stackoverflow.com/questions/1510124/program-to-find-prime-numbers – abatishchev 2014-12-11 05:01:57
@abatishchev:您的編輯無效。這個問題明確要求保持一個單一的聲明。還會引入編譯時錯誤。我會恢復它。此外,您分享的鏈接因多種原因而不同。首先,它不使用並行性。其次,它顯示了x和y之間的素數,而這個問題顯示了前N個素數,這是完全不同的概念(因爲在這種情況下你沒有上限)。 – dotNET 2014-12-11 05:35:53
@dotNET,不幸的是,在abatishchev的糟糕編輯之後,代碼中仍然存在錯誤。在Range方法中缺少結束符。 – 2014-12-11 05:44:21