了解C#中的延迟加载优化

Mig*_*lla 2 c# linq lazy-loading deferred-execution

在阅读了一些如何使用,foreach,linq延迟执行和迭代器在C#中工作之后.我决定尝试在一个小项目中优化基于属性的验证机制.结果:

private IEnumerable<string> GetPropertyErrors(PropertyInfo property)
{
    // where Entity is the current object instance
    string propertyValue = property.GetValue(Entity)?.ToString();

    foreach (var attribute in property.GetCustomAttributes().OfType<ValidationAttribute>())
    {
        if (!attribute.IsValid(propertyValue))
        {
            yield return $"Error: {property.Name} {attribute.ErrorMessage}";
        }
    }
}

// inside another method
foreach(string error in GetPropertyErrors(property))
{
    // Some display/insert log operation
}
Run Code Online (Sandbox Code Playgroud)

我觉得这很慢,但也可能是由于反射或大量的属性要处理.

所以我的问题是...... 这是最优还是很好地利用了延迟加载机制?或者我错过了什么,只是浪费了大量的资源.

注意:代码意图本身并不重要,我关心的是在其中使用延迟加载.

Ser*_*kiy 5

延迟加载不是C#或Entity Framework特有的.这是一种常见的模式,允许延迟一些数据加载.延期意味着不立即加载.有些样品需要时:

  • 在(Word)文档中加载图像.文档可能很大,可能包含数千张图像.如果您在打开文档时加载所有文件,则可能需要花费大量时间.没有人想坐下来观看加载文件30秒.在Web浏览器中使用相同的方法 - 资源不与页面主体一起发送.浏览器延迟资源加载.
  • 加载对象图.它可能是来自数据库,文件系统对象等的对象.加载完整图可能等于将所有数据库内容加载到内存中.这要花多长时间?它有效吗?不.如果您正在构建一些文件系统资源管理器,您将在开始使用之前加载有关系统中每个文件的信息吗?如果你只加载关于当前目录的信息(可能它是直接的孩子),它会快得多.

延迟加载并不总是意味着在您确实需要数据之前推迟加载.在您真正需要该数据之前,可能会在后台线程中进行加载.例如,您可能永远不会滚动到网页底部以查看页脚图像.延迟加载意味着只能推迟.C#枚举器可以帮助您.考虑获取目录中的文件列表:

string[] files = Directory.GetFiles("D:");
IEnumerable<string> filesEnumerator = Directory.EnumerateFiles("D:");
Run Code Online (Sandbox Code Playgroud)

第一种方法返回文件数组.这意味着目录应该获取其所有文件并将其名称保存到数组,然后才能获得第一个文件名.这就像在看到文档之前加载所有图像一样.

第二种方法使用枚举器 - 当您要求下一个文件名时,它会逐个返回文件.这意味着立即返回枚举器而不获取所有文件并将它们保存到某个集合中.并且您可以在需要时逐个处理文件.这里获取文件列表是推迟的.

但你应该小心.如果不延迟基础操作,那么返回枚举器将不会给您带来任何好处.例如

public IEnumerable<string> EnumerateFiles(string path)
{
    foreach(string file in Directory.GetFiles(path))
        yield return file;
}
Run Code Online (Sandbox Code Playgroud)

在这里,您使用GetFiles在返回文件名之前填充文件名数组的方法.所以逐个产生文件会给你带来速度上的好处.

在你的情况下,你有完全相同的问题 - GetCustomAttributes扩展内部使用Attribute.GetCustomAttributes返回属性数组的方法.所以你不会减少获得第一个结果的时间.

  • 这有助于我理解这些概念,谢谢 (2认同)
  • 谢谢你,有人发布了相关的东西。赞成。 (2认同)