c# - 列表中的 union vs addrange,哪个是最快且性能好的?
问题描述
您认为以下两个代码之间哪个是最好的,或者您有另一个更有效的替代方案
第一的
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}");
}
}
}
推荐阅读
- visual-studio-code - “更漂亮 - 代码格式化程序”在 Visual Studio 代码中不起作用
- c - sccz80:"../lib/main.c" L:16 警告:#14:Expected ',' sccz80:"../lib/main.c" L:16 错误:#28:分段错误
- c# - 将变量传递给已实现的 DLL 函数
- python - 从网站下载多个附件作为python中的图像
- javascript - js如何添加时间计数器onclick事件
- python - 如何从 pyscopg2 连接对象获取信息?
- c - 在链表中搜索
- voice-recognition - 创建以语音命令开始的反应原生应用程序,如谷歌助手或 alexa
- wpf - VB WPF xaml 文件引用 My.Resources
- laravel-5 - 如何在 cpanel 中启用工匠命令?