我有一個列表,我想要一個簡短而快速的方法來使其元素之一成爲第一個元素。 我想要使用下面的代碼來選擇第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