【发布时间】:2017-12-26 20:33:45
【问题描述】:
我知道以前有人问过这个问题,我找到的答案都是关于抢占和同步开销等。但是,我仍然很想知道我自己的情况的答案。所以这就是交易。
我在Intel Core i7-2670QM CPU(4 核,8 线程)上运行,我编写了以下代码:
using System;
using System.Diagnostics;
using System.Threading;
namespace _T
{
class Program
{
private static void stquicksort(object parameter)
{
object[] parameters = (object[])parameter;
int[] array = (int[])parameters[0];
int left = (int)parameters[1];
int right = (int)parameters[2];
if (left >= right) return;
int temp = (left + right) / 2;
int pivot = array[temp];
array[temp] = array[right];
int j = left;
for (int i = left; i < right; i++)
{
if (array[i] < pivot)
{
if (i != j)
{
temp = array[i];
array[i] = array[j];
array[j++] = temp;
}
else j++;
}
}
array[right] = array[j];
array[j] = pivot;
stquicksort(new object[] { array, left, j - 1 });
stquicksort(new object[] { array, j + 1, right });
}
private static void mtquicksort(object parameter)
{
object[] parameters = (object[])parameter;
int[] array = (int[])parameters[0];
int left = (int)parameters[1];
int right = (int)parameters[2];
if (left >= right) return;
int temp = (left + right) / 2;
int pivot = array[temp];
array[temp] = array[right];
int j = left;
for (int i = left; i < right; i++)
{
if (array[i] < pivot)
{
if (i != j)
{
temp = array[i];
array[i] = array[j];
array[j++] = temp;
}
else j++;
}
}
array[right] = array[j];
array[j] = pivot;
Thread t = new Thread(mtquicksort);
t.Start(new object[] { array, left, j - 1 });
mtquicksort(new object[] { array, j + 1, right });
t.Join();
}
private static void dump(int[] array)
{
Console.Write("Array:");
foreach (int el in array) Console.Write(" " + el);
Console.WriteLine();
}
private static void Main(string[] args)
{
while (true)
{
Console.Write("Enter the number of elements: ");
int count = Convert.ToInt32(Console.ReadLine());
if (count < 0) break;
Random rnd = new Random();
int[] array1 = new int[count];
for (int i = 0; i < array1.Length; i++)
array1[i] = rnd.Next(1, 100);
int[] array2 = (int[])array1.Clone();
Stopwatch sw = new Stopwatch();
sw.Reset(); sw.Start();
stquicksort(new object[] { array1, 0, array1.Length - 1 });
sw.Stop();
Console.WriteLine("[ST] Time needed: " + sw.ElapsedMilliseconds + "ms");
sw.Reset(); sw.Start();
mtquicksort(new object[] { array2, 0, array2.Length - 1 });
sw.Stop();
Console.WriteLine("[MT] Time needed: " + sw.ElapsedMilliseconds + "ms");
}
Console.WriteLine("Press any key to exit . . .");
Console.ReadKey(true);
}
}
}
stquicksort 是单线程的,mtquicksort 是多线程的,是的,我故意这样保留 st 参数,因此两个版本的装箱/拆箱开销是相同的(如果有的话)。我已经发布了解决方案(禁用了所有调试),输出有点难过:
Enter the number of elements: 100
[ST] Time needed: 0ms
[MT] Time needed: 323ms
Enter the number of elements: 1000
[ST] Time needed: 0ms
[MT] Time needed: 7476ms
Enter the number of elements: 1000
[ST] Time needed: 0ms
[MT] Time needed: 7804ms
Enter the number of elements: 1000
[ST] Time needed: 0ms
[MT] Time needed: 7474ms
Enter the number of elements: 10
[ST] Time needed: 0ms
[MT] Time needed: 32ms
Enter the number of elements: 100
[ST] Time needed: 0ms
[MT] Time needed: 339ms
再说一遍,问题是先发制人的,是不是代码中的缺陷?更重要的是,解决这个问题的正确方法是什么。
【问题讨论】:
-
为什么不计算独立于您的快速排序的线程成本.....您可以回答自己的问题
-
@KeithNicholas 当然,我正在摆弄它,但想听听其他一些建议和意见,以及在这个具体情况下:)
-
您应该尝试对更多元素进行排序,例如 1M、10M、100M
-
@Jason 试过了,async/await & tasks 实际上会导致 stackoverflow,而使用线程它仍然非常非常慢。
标签: c# multithreading quicksort