[英]C# Is there anything faster than PLINQ for averaging 10million item array while grouing
我基本上是在嘗試找到一種方法,以最快的速度進行分組時平均產生1000萬個館藏。 以下是我用作基准的代碼,但我似乎找不到任何使它更快的方法。 我正在根據StopWatrch mainSW
這是我的Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpeedTest
{
class Program
{
static void Main(string[] args)
{
global.BuildItems();
System.Diagnostics.Stopwatch mainSW = new System.Diagnostics.Stopwatch();
mainSW.Start();
baseLineTest.plinqGroup();
Console.WriteLine("Press Return");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Main SW Elapsed:" + mainSW.Elapsed);
Console.ReadLine();
}
}
}
這是我的global.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpeedTest
{
class global
{
//10 million
public static long globalIteration = 10000000;
private static string[] classOptions = { "AS", "CS", "LS", "PE", "WP", "LS" };
public static Items[] items { get; set; }
public static void BuildItems()
{
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
Random r = new Random();
Random r2 = new Random();
Console.WriteLine("Building list");
items = new Items[globalIteration];
sw.Start();
for (int i = 0; i < globalIteration; i++)
{
items[i] = new Items();
items[i].cl = classOptions[r.Next(0, 5)];
items[i].uc = Convert.ToDecimal(r.Next(300, 1000));
}
Console.WriteLine("Building list sw: " + sw.Elapsed);
}
}
class Items
{
public decimal uc;
public string cl;
}
}
這是我的baseLineTest.cs
using System;
using System.Linq;
using System.Threading.Tasks;
namespace SpeedTest
{
class baseLineTest
{
public static void plinqGroup()
{
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
Console.WriteLine("This test is a plinq over an array");
decimal avg = 0;
decimal sum = 0;
string clas = "";
sw.Start();
var list = global.items.AsParallel().GroupBy(d => d.cl)
.Select(
g => new
{
Key = g.Key,
Value = g.Average(s => s.uc)
});
foreach (var item in list)
Console.WriteLine(string.Format("{0} : {1} ", item.Key, item.Value));
Console.WriteLine("PLinq Group elapsed : " + sw.Elapsed);
}
}
}
這取決於您對數據的了解程度。 如果使用數據的代碼知道“ classOptions”,那么可以通過首先創建一個結果對象數組然后使用Parallel.ForEach來使其快兩倍(至少在我的四核計算機上)。操作數組
[TestMethod]
public void MeasureParallelForEach()
{
string[] classOptions = { "AS", "CS", "LS", "PE", "WP", "LS" };
global.BuildItems();
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
Console.WriteLine("This test is a plinq over an array");
sw.Start();
IDictionary<string, Group> groups = global.classOptions.Distinct().ToDictionary(x => x, x => new Group(x));
Parallel.ForEach(global.items, d => groups[d.cl].Add(d.uc));
foreach (var item in groups)
Console.WriteLine(string.Format("{0} : {1} ", item.Key, item.Value.Average));
Console.WriteLine("Parallel.ForEach elapsed : " + sw.Elapsed);
}
public class Group
{
private int count;
private decimal sum;
public Group(string key)
{
Key = key;
}
public void Add(decimal d)
{
sum += d;
count++;
}
public string Key { get; private set; }
public decimal Average { get { return count==0?0m:sum/count; }}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.