C# 用于查找数组中少数元素之和的并行代码(子问题)
我有以下C#代码片段:C# 用于查找数组中少数元素之和的并行代码(子问题),c#,algorithm,data-structures,loops,mono,C#,Algorithm,Data Structures,Loops,Mono,我有以下C#代码片段: using System; class count { public static void Main() { int [] a = {-30, 30, -20, -10, 40, 0, 10, 5}; int i,j,k; int N=8; for (i=0; i < N; ++i) for (j=i+1; j < N; ++j) for (k=j+1; k < N; ++k) if (a[i] + a[
using System;
class count {
public static void Main()
{
int [] a = {-30, 30, -20, -10, 40, 0, 10, 5};
int i,j,k;
int N=8;
for (i=0; i < N; ++i)
for (j=i+1; j < N; ++j)
for (k=j+1; k < N; ++k)
if (a[i] + a[j] + a[k] == 30)
Console.WriteLine (a[i].ToString () + a[j].ToString() + a[k].ToString());
}
}
使用系统;
班级人数{
公共静态void Main()
{
int[]a={-30,30,-20,-10,40,0,10,5};
int i,j,k;
int N=8;
对于(i=0;i
上面的程序所做的是,从数组A中找出三元组a1、a2、a3,这样三元组的总和就是30
我想知道如何使用C#Parallel.来进行求和计算
我知道这是一个面试问题,有比I,j,k循环更好的替代算法。但是,我只想了解如何使用C#的并行扩展有效地执行此操作 dan的答案会起作用,并且是使用
并行的正确方法。对于
,但是我经历了分析代码的麻烦,我想你会发现并行化并不会使它更快。每个Parellel.For
都会生成几个新线程,通常超过三个,因此对于3个嵌套的Parellel.For
s,您将拥有至少3^3(27)个线程,这比任何机器上的逻辑处理器数量都要多。额外的线程会增加开销并降低速度
那么,为什么不让一个并行。对于
和两个普通用于
循环-这意味着大约有3-4个线程可以在双核或四核机器上工作。像这样的方法:
static void Test2(int[] a)
{
int N = a.Length;
int total = 0;
Object locker = new object();
Parallel.For(0, N, i =>
{
for (int j = i + 1; j < N; ++j)
for (int k = j + 1; k < N; ++k)
if (a[i] + a[j] + a[k] == 30)
lock(locker)
total++;
});
}
+我完全同意。事实上,我会问这个作为面试问题,如果他们给了我丹的答案,我会扣分,因为这表明他们不明白“为什么”你应该使用paralelf,而只是“如何”使用paralelforkept,意思是自己写这样的答案,但太懒了。干得好,谢谢大家的回答。正如我提到的,我并不是真的在寻找一个完美的解决方案。但是想知道如何在C#中实现这一点。你的解决方案太棒了。谢谢大家。为什么不联锁。增量?
class Program
{
static void Main(string[] args)
{
Random r = new Random();
int[] arr = new int[100];
arr = arr.Select(i => r.Next(-30, 30)).ToArray();
Profile(Test0, arr, 20);
Profile(Test1, arr, 20);
Profile(Test2, arr, 20);
Console.WriteLine("Test0: {0} ms", Profile(Test0, arr, 100).TotalMilliseconds);
Console.WriteLine("Test1: {0} ms", Profile(Test1, arr, 100).TotalMilliseconds);
Console.WriteLine("Test2: {0} ms", Profile(Test2, arr, 100).TotalMilliseconds);
Console.ReadLine();
}
static void Test0(int[] a)
{
int N = a.Length;
int total = 0;
for (int i = 0; i < N; ++i)
for (int j = i + 1; j < N; ++j)
for (int k = j + 1; k < N; ++k)
if (a[i] + a[j] + a[k] == 30)
total++;
}
static void Test1(int[] a)
{
int N = a.Length;
int total = 0;
Object locker = new object();
Parallel.For(0, N, i => Parallel.For(i+1, N, j => Parallel.For(j+1, N, k =>
{
if (a[i] + a[j] + a[k] == 30)
lock(locker)
total++;
})));
}
static void Test2(int[] a)
{
int N = a.Length;
int total = 0;
Object locker = new object();
Parallel.For(0, N, i =>
{
for (int j = i + 1; j < N; ++j)
for (int k = j + 1; k < N; ++k)
if (a[i] + a[j] + a[k] == 30)
lock(locker)
total++;
});
}
static TimeSpan Profile<T>(Action<T> action, T param, int repeats)
{
Stopwatch s = new Stopwatch();
for (int i = 0; i < repeats; i++)
{
s.Start();
action(param);
s.Stop();
}
return new TimeSpan(s.ElapsedTicks/repeats);
}
}
Test0: 0.2544 ms
Test1: 3.3433 ms
Test2: 0.1391 ms