【发布时间】:2021-11-24 10:50:53
【问题描述】:
我正在做一个比较时间泡和选择排序的项目。我制作了两个单独的程序并将它们组合成一个程序,现在冒泡排序比选择排序运行得快得多。我检查以确保代码不只是因为某些转换错误而给我 0 并且按预期运行。我正在使用System.Diagnostics; 来测量时间。我还检查了机器没有问题,我在Replit上运行它并得到了类似的结果。
{
class Program
{
public static int s1 = 0;
public static int s2 = 0;
static decimal bubblesort(int[] arr1)
{
int n = arr1.Length;
var sw1 = Stopwatch.StartNew();
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (arr1[j] > arr1[j + 1])
{
int tmp = arr1[j];
// swap tmp and arr[i] int tmp = arr[j];
arr1[j] = arr1[j + 1];
arr1[j + 1] = tmp;
s1++;
}
}
}
sw1.Stop();
// Console.WriteLine(sw1.ElapsedMilliseconds);
decimal a = Convert.ToDecimal(sw1.ElapsedMilliseconds);
return a;
}
static decimal selectionsort(int[] arr2)
{
int n = arr2.Length;
var sw1 = Stopwatch.StartNew();
// for (int e = 0; e < 1000; e++)
// {
for (int x = 0; x < arr2.Length - 1; x++)
{
int minPos = x;
for (int y = x + 1; y < arr2.Length; y++)
{
if (arr2[y] < arr2[minPos])
minPos = y;
}
if (x != minPos && minPos < arr2.Length)
{
int temp = arr2[minPos];
arr2[minPos] = arr2[x];
arr2[x] = temp;
s2++;
}
}
// }
sw1.Stop();
// Console.WriteLine(sw1.ElapsedMilliseconds);
decimal a = Convert.ToDecimal(sw1.ElapsedMilliseconds);
return a;
}
static void Main(string[] args)
{
Console.WriteLine("Enter the size of n");
int n = Convert.ToInt32(Console.ReadLine());
Random rnd = new System.Random();
decimal bs = 0M;
decimal ss = 0M;
int s = 0;
int[] arr1 = new int[n];
int tx = 1000; //tx is a variable that I can use to adjust sample size
decimal tm = Convert.ToDecimal(tx);
for (int i = 0; i < tx; i++)
{
for (int a = 0; a < n; a++)
{
arr1[a] = rnd.Next(0, 1000000);
}
ss += selectionsort(arr1);
bs += bubblesort(arr1);
}
bs = bs / tm;
ss = ss / tm;
Console.WriteLine("Bubble Sort took " + bs + " miliseconds");
Console.WriteLine("Selection Sort took " + ss + " miliseconds");
}
}
}
发生了什么事?是什么导致冒泡排序变快或减慢选择排序?我该如何解决这个问题?
我发现问题在于,除了针对样本大小的 1000 次运行之外,选择排序在每个方法运行中循环 1000 次,导致该方法的性能明显低于冒泡排序。谢谢大家的帮助,也感谢 TheGeneral 向我展示了基准测试工具。此外,作为参数给出的数组是副本而不是引用,因为手动运行循环向我显示冒泡排序正在完成它的工作,而不是对已经排序的数组进行排序。
【问题讨论】:
-
衡量性能几乎是一门艺术。您需要多次运行,并且需要混淆它们运行的顺序,这样一个就不会“热身”另一个。还要确保它不是调试版本。还要确保使用 相同 数据集。这里有很多很多这样的帖子解释更多
-
冒泡排序在已经排序的数组上运行,所以它不需要对任何东西进行排序。在执行之前尝试深度复制输入数组并在单独的实例上运行函数。
-
顺便说一下,除了对已经排序的数组进行排序之外,您的冒泡排序还没有正确实现——它不是自适应的。正确实现的冒泡排序不会重新排序已经排序的数组,如果没有发生交换,它也不会检查第一个完整循环 - 即使没有交换,你的仍然会执行 O(n^2) 检查正在发生。正确实施的冒泡排序通常会击败选择排序。查看这个有用的网站:toptal.com/developers/sorting-algorithms
标签: c# sorting bubble-sort selection-sort