哪个是你认为下面两个代码之间最好的,还是你有另一种更有效的替代方案
第一
List<int> g = new List<int>();
g.AddRange(listof1);
g.AddRange(listof2);
return g.GroupBy(a=>a)
.Select(root=>root.FirstOrDefault())
.ToList();
第二
var rootIds = listof1.
Union(listof2)
.Select(rootId => rootId).ToList();
return rootIds;
-
没关系
-
让我们看看:)
实验
候选人
static int M1(List<int> l1, List<int> l2)
{
List<int> g = new List<int>();
g.AddRange(l1);
g.AddRange(l2);
var x = g.GroupBy(a => a)
.Select(root => root.FirstOrDefault())
.ToList();
return x.Count();
}
static int M2(List<int> l1, List<int> l2)
{
var x = l1
.Union(l2)
.Select(rootId => rootId).ToList();
return x.Count();
}
static int M3(List<int> l1, List<int> l2)
{
var g = new HashSet<int>(l1);
g.UnionWith(l2);
return g.Count();
}
结果
100.00
0.057 0.038 0.017 res: 200,200,200
0.040 0.015 0.011 res: 200,200,200
0.055 0.023 0.009 res: 200,200,200
0.062 0.036 0.022 res: 200,200,200
0.055 0.023 0.027 res: 200,200,200
1,000,000.00
1788.493 513.422 292.815 res: 1999068,1999068,1999068
1795.416 591.142 453.076 res: 1999068,1999068,1999068
2540.099 529.801 303.729 res: 1999068,1999068,1999068
1797.251 527.849 428.672 res: 1999068,1999068,1999068
2008.561 527.680 501.997 res: 1999068,1999068,1999068
10,000,000.00
34458.838 6764.472 3679.255 res: 19906255,19906255,19906255
32756.011 8507.293 3875.931 res: 19906255,19906255,19906255
测试代码
public class Program
{
static Random r = new Random(1);
public static async Task Main(string[] args)
{
Try(100);
Try(1000000);
Try(10000000);
Console.ReadLine();
}
public static void Try(int i)
{
var l1 = Enumerable.Range(0, i).Select(i => r.Next(0, int.MaxValue)).ToList();
var l2 = Enumerable.Range(0, i).Select(i => r.Next(0, int.MaxValue)).ToList();
NapkinQualityCompareMeasureIt(i, 5, fs: new List<Func<int>> { () => M1(l1, l2), () => M2(l1, l2), () => M3(l1, l2) });
}
public static void NapkinQualityCompareMeasureIt<T>(int count, int howManyTimes, List<Func<T>> fs)
{
//This is good only for detecting significant differences
Console.WriteLine(count.ToString("N"));
for (int i = 0; i < howManyTimes; i++)
{
var metrics = fs.Select(f =>
{
var sw = Stopwatch.StartNew();
var r = f();
return (Elapsed: sw.Elapsed, Result: r);
});
var res = string.Join(",", metrics.Select(m=>m.Result));
var times = string.Join("", metrics.Select(m => $"{m.Elapsed.TotalMilliseconds.ToString("F3").PadRight(12)}"));
Console.WriteLine($"{times}tres: {res}");
}
}
}
如果你想要一组唯一的值,HashSet<int>
值得考虑:
var g = new HashSet<int>(listof1);
g.UnionWith(listof2);
使用HashSet
的优点是它不可能包含重复值 - 使使用g
的代码更易于阅读和推理。