gpt4 book ai didi

c# - linq .Cast<> 或在 ConvertAll 内转换列表

转载 作者:行者123 更新时间:2023-12-04 00:39:46 26 4
gpt4 key购买 nike

考虑到您必须转换 mylist类型 List<T>List<Base>其中 TBase 的子类

这些解决方案是否相同?哪个性能更好,为什么?我应该什么时候更喜欢使用第一个或第二个?

return mylist.Cast<Base>().ToList();

return mylist.ConvertAll(x => (Base)x);

也许第二种解决方案会更好,因为 mylist 是直接转换的。

在第一个解决方案中,列表被转换为 IEnumerable,然后是列表,但我不确定。

最佳答案

TL;DR:ConvertAll 进行了 1 次内存分配,但在大多数情况下 .Cast.ToList 分配了不止一次。

大多数 LINQ 扩展(如 .Cast<T>() )导致无法转换为 IEnumerable<T>(无法获得结果的 ICollection<T>)的延迟执行 .Count

当结果可以转换为 ICollection<T> 时, .ToList .ToArray 可以只进行一次内存分配来复制元素,但如果不能:

  • 最初为非空源分配4个元素的缓冲区数组
  • 当更多元素需要空间时,新数组分配的大小是前一个数组的两倍
  • 元素从旧数组复制到新数组,旧数组稍后由垃圾收集器释放。

更新

令人惊讶的是,差异似乎并没有我预期的那么显着:

method      elapsed             ratio               count

Cast.ToList 00:00:14.4487329 1.3719890831991 123456789
ConvertAll 00:00:10.5312302 0.728868773261865

Cast.ToList 00:00:01.4959734 1.50233158227713 12345678
ConvertAll 00:00:00.9957678 0.665632016125407

Cast.ToList 00:00:00.1252968 2.45948743599897 1234567
ConvertAll 00:00:00.0509442 0.40658878161491

Cast.ToList 00:00:00.0082611 3.99145006839945 123456
ConvertAll 00:00:00.0020697 0.250535515380002

Cast.ToList 00:00:00.0008097 0.620558719826417 12345
ConvertAll 00:00:00.0013049 1.61145104895105

Cast.ToList 00:00:00.0001812 0.193207547169811 1234
ConvertAll 00:00:00.0009378 5.17578125

Cast.ToList 00:00:00.0001433 0.149501661129568 123
ConvertAll 00:00:00.0009587 6.68888888888889

所以,赛马!

int c = 123; var L = Enumerable.Range(0, c).ToList();

GC.Collect(); var sw1 = Stopwatch.StartNew(); L.Cast<object>().ToList(); sw1.Stop();

GC.Collect(); var sw2 = Stopwatch.StartNew(); L.ConvertAll(i => (object)i); sw2.Stop();

MessageBox.Show($"Cast.ToList\t{sw1.Elapsed}\t{(double)sw1.ElapsedTicks / sw2.ElapsedTicks}\n" +
$"ConvertAll \t{sw2.Elapsed}\t{(double)sw2.ElapsedTicks / sw1.ElapsedTicks}");

关于c# - linq .Cast<> 或在 ConvertAll 内转换列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42427912/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com