【发布时间】:2019-02-20 20:31:35
【问题描述】:
我正在尝试找到一种方法来尽可能快地对列表进行排序。我知道我将使用的“桶排序”(我认为?)。但在这样做之前。我想我首先在寻找最快的干净算法,然后在桶排序中使用它?
字符串如下所示,我在循环中添加了 100.000 个元素:
-0,awb/aje - ddfas/asa - asoo/qwa
-1,awb/aje - ddfas/asa - asoo/qwa
-2,awb/aje - ddfas/asa - asoo/qwa
所以我想对第一个以逗号分隔的参数进行降序排序,它是一个双精度参数:-0、-1、-2 等。
我尝试了 3 种方法,其中只有方法 1 真正正确排序。方法 2 和 3 不能完全正确地按数字降序排序。
因此,正确排序的方法 1 可以在 30 秒内完成。 问题是我将有大约 300 万个元素,而不仅仅是 100.000,就像在这个例子中那样,这至少需要 900 秒或更长时间。
我的问题是我们如何才能尽可能快地对 100.000 个或更多正确的 300 万个元素进行排序? 运行:sortingtestBENCHMARKS() 将显示结果
public void sortingtestBENCHMARKS()
{
List<String> dataLIST = new List<String>(); List<String> sortedLIST = new List<String>(); String resultString = ""; int index = 0;
DateTime starttime = DateTime.Now; DateTime endtime = DateTime.Now; TimeSpan span = new TimeSpan();
for (double i = 0; i < 100000; i+=1)
{
dataLIST.Add("-" + i + "," + "awb/aje" + " - " + "ddfas/asa" + " - " + "asoo/qwa");
}
dataLIST = shuffle(dataLIST);
/*--------------------------------------------------------------------------*/
//APPROACH 1: 30 seconds (Sorts correctly in descending order)
starttime = DateTime.Now;
dataLIST = sortLIST(dataLIST);
endtime = DateTime.Now;
span = endtime - starttime;
resultString = "Approach 1: " + span.TotalSeconds;
dataLIST = shuffle(dataLIST);
/*--------------------------------------------------------------------------*/
//APPROACH 2: 55 seconds (Sorts INcorrectly in descending order)
starttime = DateTime.Now;
for (int i = 0; i < dataLIST.Count; i++)
{
index = sortedLIST.BinarySearch(dataLIST[i]);
if (index < 0)
{
sortedLIST.Insert(~index, dataLIST[i]);
}
}
endtime = DateTime.Now;
span = endtime - starttime;
resultString = resultString + "\nApproach 2: " + span.TotalSeconds;
/*--------------------------------------------------------------------------*/
//APPROACH 3: 2 seconds (Sorts INcorrectly in descending order)
starttime = DateTime.Now;
dataLIST.Sort(); //1.6 seconds
endtime = DateTime.Now;
span = endtime - starttime;
resultString = resultString + "\nApproach 3: " + span.TotalSeconds;
/*--------------------------------------------------------------------------*/
MessageBox.Show("Elapsed Times:\n\n" + resultString);
}
List<String> sortLIST(List<String> theLIST)
{
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
theLIST.Sort(new Comparison<String>((a, b) =>
{
int result = 0;
double ad = 0;
double bd = 0;
NumberFormatInfo provider = new NumberFormatInfo();
provider.NumberGroupSeparator = ",";
provider.NumberDecimalSeparator = ".";
provider.NumberGroupSizes = new int[] { 5 };
ad = Convert.ToDouble(a.Replace("a", "").Replace("c", "").Split(',')[0], provider);
bd = Convert.ToDouble(b.Replace("a", "").Replace("c", "").Split(',')[0], provider);
if (ad < bd)
{
result = 1;
}
else if (ad > bd)
{
result = -1;
}
return result;
}));
return theLIST;
}
List<String> shuffle(List<String> list)
{
var randomizedList = new List<String>();
var rnd = new Random();
while (list.Count != 0)
{
var index = rnd.Next(0, list.Count);
randomizedList.Add(list[index]);
list.RemoveAt(index);
}
return randomizedList;
}
【问题讨论】:
-
你想达到什么目的?你不能使用 Arrays.sort()/Collections.sort()/TreeSet 和适当的比较器(例如 Comparator::reverseOrder)吗?
-
是的,我的代码中的方法 1 确实使用了使用比较器的排序算法。但我正在寻找是否有更智能/更好的解决方案,因为它需要 30 秒。仅使用标准的 Collections.Sort() 方法只需 2 秒,但它并没有按照我们所知的完全正确的降序排序。
-
您应该始终包含您正在使用的语言的标签!一旦没有语言,页面根本不会突出显示代码。
-
(是的,你是对的,我添加了 c# 作为问题的标签)
-
你实际上是在比较不同的东西,你写的那个“比较器”正在做很多低效的事情。此外,如果您在排序时将所有内容都转换为双精度,那么为什么列表首先不是双精度的?
标签: c# list performance sorting