gpt4 book ai didi

C# Foreach 优化与反射

转载 作者:行者123 更新时间:2023-11-30 14:08:53 31 4
gpt4 key购买 nike

基本上,这段代码是:

// Get these once, create list, re-use same list
var prodType = products.GetType();
var fieldInfList = prodType.GetFields();
var propInfList = prodType.GetProperties();

foreach (var p in products)
{
foreach (var fieldInf in fieldInfList)
{
fieldInf.SetValue(this, fieldInf.GetValue(p));
}
foreach (var propInf in propInfList)
{
propInf.SetValue(this, propInf.GetValue(p));
}
}

比这更快:

foreach (var p in products)
{
foreach (var fieldInf in products.GetType().GetFields())
{
fieldInf.SetValue(this, fieldInf.GetValue(p));
}
foreach (var propInf in products.GetType().GetProperties())
{
propInf.SetValue(this, propInf.GetValue(p));
}
}

...?

我的想法是,对于第二个 block ,每个循环都将再次检查对象,而第一个 block 将在每个循环中持续存在。

同理

var prodType = products.GetType();

类型只会被检索一次。

或者编译器/.Net 是否只是在第二个示例中重复使用相同的列表而不需要我做任何事情?如何比较创建新列表与重复获取对象属性的开销?垃圾收集器会以不同方式处理我创建的列表,导致它停留更长时间吗?

非常感谢任何回答或指出正确的方向。

最佳答案

Or does the compiler / .Net just re-use the same list in the second example without me having to do anything?

如果它知道反射 API 是幂等的并且生成的对象在观察上是纯的,它就可以做到这一点。它不知道。不会进行此优化。理论上,调用任何反射 API 都可以打印到控制台。 JIT 必须执行调用才能确定。

事实上,即使这样,它也不是一个安全的优化,因为反射 API 可能会抛出异常,并且只有在外循环至少进行一次迭代时才会引发该异常。

是的,分解列表会导致性能提升。

How do I compare the overhead of creating a new list with getting the object properties repeatedly?

也不确定你的意思。测量。

Would the garbage collector treat my created list any differently causing it to hang around longer?

这对 GC 没有影响,因为属性列表很小(可能只有几百个字节,具体取决于属性的数量)。

我想排除列表会导致该列表保持事件状态的时间稍长一点,因为列表将保持事件状态直到外部循环完成(至少在 CLR 的当前实现中是这样)。

关于C# Foreach 优化与反射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32563446/

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