-3
我有一個內存列表,包含大約100萬條記錄(多個列)(日期,名稱,值,Id,.....)按多個標準排序列表<T>的首選方式是什麼?
我的問題:什麼是最佳解決方案(即提供最佳性能)用多列來排序這麼大的列表?
例(僞代碼):
list.orderbyDesc(name).thenBy(Name).thenBy(Value)
我有一個內存列表,包含大約100萬條記錄(多個列)(日期,名稱,值,Id,.....)按多個標準排序列表<T>的首選方式是什麼?
我的問題:什麼是最佳解決方案(即提供最佳性能)用多列來排序這麼大的列表?
例(僞代碼):
list.orderbyDesc(name).thenBy(Name).thenBy(Value)
原則上有兩種方式來排序您的泛型列表:
使用LINQ的方法鏈:
var orderedEnumerable = list.OrderByDescending(item => item.Property0)
.ThenBy(item => item.Property1)
.ThenBy(item => item.Property2);
使用實現IComparer<T>
的自定義比較器。通過比較器,你可以創建一個新的有序枚舉
var orderedEnumerable = list.OrderBy(item => item, new MyComparer());
,或者您可以使用Sort()
方法就地排序:
list.Sort(new MyComparer());
嘗試標杆不同的方法(提示:我d原則上希望原地運行最快的List<T>.Sort(IComparer<T>)
,但這一切取決於您是否要列舉Enumerable.OrderBy
的整個結果)。
下面是一個簡單的基準樣本打轉轉:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
class Record
{
public string Name { get; set; }
public int Age { get; set; }
public double Salary { get; set; }
}
class RecordComparer : IComparer<Record>
{
public int Compare(Record x, Record y)
{
// Sort by Name, Age, and then Salary
if (x.Name != y.Name) return x.Name.CompareTo(y.Name);
if (x.Age != y.Age) return x.Age.CompareTo(y.Age);
return x.Salary.CompareTo(y.Salary);
}
}
class Program
{
static Random _random = new Random();
static List<Record> _list;
static void Main(string[] args)
{
Profile("SortUsingLinqMethodChain", 50, InitList, SortUsingLinqMethodChain);
Profile("SortUsingLinqComparer", 50, InitList, SortUsingLinqComparer);
Profile("SortUsingListSort", 50, InitList, SortUsingListSort);
}
static void InitList()
{
_list = new List<Record>();
for (int i = 0; i < 10000; i++)
{
_list.Add(new Record { Name = RandomString(12), Age = RandomAge() });
}
}
static void SortUsingLinqMethodChain()
{
// NOTE: the `ToList` materialization may not be necessary at all
// This totally depends on what you want to do with the result.
_list = _list.OrderBy(item => item.Name)
.ThenBy(item => item.Age)
.ThenBy(item => item.Salary).ToList();
}
static void SortUsingLinqComparer()
{
// NOTE: the `ToList` materialization may not be necessary at all
// This totally depends on what you want to do with the result.
_list = _list.OrderBy(item => item, new RecordComparer()).ToList();
}
static void SortUsingListSort()
{
_list.Sort(new RecordComparer());
}
// based on http://stackoverflow.com/a/1344242/40347
public static string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[_random.Next(s.Length)]).ToArray());
}
public static int RandomAge()
{
return _random.Next(100) + 1;
}
public static double RandomSalary()
{
return _random.NextDouble() * 100000;
}
// based on http://stackoverflow.com/a/1048708/40347
static double Profile(string description, int iterations, Action init, Action func)
{
// Run at highest priority to minimize fluctuations
// caused by other processes/threads
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
Thread.CurrentThread.Priority = ThreadPriority.Highest;
// warm up
init();
func();
var watch = new Stopwatch();
// clean up
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
for (int i = 0; i < iterations; i++)
{
init();
watch.Start();
func();
watch.Stop();
}
Console.Write(description);
Console.WriteLine(" Time Elapsed {0} ms", watch.Elapsed.TotalMilliseconds);
return watch.Elapsed.TotalMilliseconds;
}
}
你如何排序'List'做什麼研究?你發現了什麼?你有什麼問題執行你在研究中找到的解決方案? – Servy
我想分揀,但我認爲這是不夠的,我需要的表現 –
數據如何存儲?它只是一個內存中的List?你如何得到它? – enkryptor