我有一个列表,我想要一个简短而快速的方法来使其元素之一成为第一个元素。 我想要使用下面的代码来选择第10个元素并使其成为第一个元素。但是,寻找更好的SOLN使列表中的元素成为第一个元素的最快方法
tempList.Insert(0, tempList[10]);
tempList.RemoveAt(11);
我有一个列表,我想要一个简短而快速的方法来使其元素之一成为第一个元素。 我想要使用下面的代码来选择第10个元素并使其成为第一个元素。但是,寻找更好的SOLN使列表中的元素成为第一个元素的最快方法
tempList.Insert(0, tempList[10]);
tempList.RemoveAt(11);
,如果你不介意的话,其余的排序,你实际上可以在0位和10交换两个项目,认为它比做插入和删除更好:
var other = tempList[0];
tempList[0]=tempList[10];
tempList[10] = other;
,你甚至可以使这个名单的,易于使用的延伸,是这样的:
public static void Swap<T>(this List<T> list, int oldIndex, int newIndex)
{
// place the swap code here
}
还有一些特殊情况下,当你可以得到更好的性能(SIMPL着想孵化城,我假设值,其中它是从所采取的位置之前总是插入):
class Program
{
const int Loops = 10000;
const int TakeLoops = 10;
const int ItemsCount = 100000;
const int Multiplier = 500;
const int InsertAt = 0;
static void Main(string[] args)
{
var tempList = new List<int>();
var tempDict = new Dictionary<int, int>();
for (int i = 0; i < ItemsCount; i++)
{
tempList.Add(i);
tempDict.Add(i, i);
}
var limit = 0;
Stopwatch
sG = new Stopwatch(),
s1 = new Stopwatch(),
s2 = new Stopwatch();
TimeSpan
t1 = new TimeSpan(),
t2 = new TimeSpan();
for (int k = 0; k < TakeLoops; k++)
{
var takeFrom = k * Multiplier + InsertAt;
s1.Restart();
for (int i = 0; i < Loops; i++)
{
tempList.Insert(InsertAt, tempList[takeFrom]);
tempList.RemoveAt(takeFrom + 1);
}
s1.Stop();
t1 += s1.Elapsed;
s2.Restart();
for (int i = 0; i < Loops; i++)
{
var e = tempDict[takeFrom];
for (int j = takeFrom - InsertAt; j > InsertAt; j--)
{
tempDict[InsertAt + j] = tempDict[InsertAt + j - 1];
}
tempDict[InsertAt] = e;
}
s2.Stop();
t2 += s2.Elapsed;
if (s2.Elapsed > s1.Elapsed || limit == 0)
limit = takeFrom;
}
sG.Start();
for (int k = 0; k < TakeLoops; k++)
{
var takeFrom = k * Multiplier + InsertAt;
if (takeFrom >= limit)
{
for (int i = 0; i < Loops; i++)
{
tempList.Insert(InsertAt, tempList[takeFrom]);
tempList.RemoveAt(takeFrom + 1);
}
}
else
{
for (int i = 0; i < Loops; i++)
{
var e = tempDict[takeFrom];
for (int j = takeFrom - InsertAt; j > InsertAt; j--)
{
tempDict[InsertAt + j] = tempDict[InsertAt + j - 1];
}
tempDict[InsertAt] = e;
}
}
}
sG.Stop();
Console.WriteLine("List: {0}", t1);
Console.WriteLine("Dictionary: {0}", t2);
Console.WriteLine("Optimized: {0}", sG.Elapsed);
/***************************
List: 00:00:11.9061505
Dictionary: 00:00:08.9502043
Optimized: 00:00:08.2504321
****************************/
}
}
在上面的例子,一个Dictionary<int,int>
被用来存储每个元素的索引。如果insertAt
和takeFrom
之间的差距较小,您将获得更好的结果。随着间隔的增加,性能会下降。我想你可能想要评估这个差距,并根据它的价值来选择最佳分支。
为什么不''var e = tempDict [10];'?除此之外:我不敢相信这比以某种方式使用插入/删除更快。这些方法在内部复制了运行时通常很好支持的数组。 – oddparity
你是对的,已更新。测试表明,它的速度更快一些'[insertAt,takeFrom]'间隔大小。 –
你期望得到多快?.. – Sayse
你的解决方案似乎不是很糟糕。 – algreat
我想确保在C#中不存在这样的代码,以便避免重复的代码。 – electricalbah