C#中 使用yield return 优化大数组或集合的访问

news2024/9/22 1:08:56

概要

我们在开发过程中,经常需要在一个很大的数组或集合中搜索元素,以满足业务需求。

本文主要介绍通过使用yield return的方式,避免将大量数据全部加载进入内存,再进行处理。从而提高程序的性能。

设计和实现

基本业务场景,我们需要在10000台ATM的数据中找前100台品牌是BrandA的ATM机的数据。

我们不再使用传统的方式,将10000台ATM机的数据全部载入内容,再进行过滤查找。

我们通过yield return方式,只返回一个迭代器,代码如下:

本例中,存在BrandA和BrandB两个品牌,在生成ATM的L集合序列时候,每次都是随机生成ATM机的品牌。

public IEnumerable<ATM> getATMListYield(){
    List<ATM> atms = new List<ATM>();
    int count = 0;
    for(var i=0; i< 10000; ++i){
        yield return new ATM (){
            Id = i,
            Name = "Atm" + i,
            Brand =  getBrand()
        } ;
    }
    yield break;
}
private string getBrand(){
    Random rd = new Random();
    int count = rd.Next(100);
    if (count >= 50) return "BrandA";
    return "BrandB";
}

调用getATMListYield,进行过滤,找到前100个BrandA的ATM机。完整代码,请参考附录。

 public void runGetList(){
     DataProvider dp = new DataProvider();
     var lists = dp.getATMList();
     var count = 0;
     foreach(var atm in lists){
         if(atm.Brand == "BrandA") {
             Console.WriteLine(atm.Name );
             ++ count;
         }
         if (count == 100){
             break;
         }
     }
 }

在foreach循环中,每次访问ATM的集合,只将集合中的一个元素载入内存,进行过滤和比较,当找到100个BrandA的元素,程序停止,不再载入ATM数组的其它元素。

载入全部ATM数据,再进行过滤的代码请见附录。

我们使用Benchmark对两种实现的性能进行测试,测试结果如下:

在这里插入图片描述
从测试结果中,可以看出,使用yield return方式,运行时间几乎减少了一半。

由于不需要将全部ATM数据载入内容,yield return方式的内存使用量,仅仅相当于传统方法的2%左右。

附录

Programs.cs

using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Net.Mail;
using System.ComponentModel.Design.Serialization;
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Collections.Generic;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Diagnosers;
namespace IQueryableIEnumerable
{
    [MemoryDiagnoser]
    public class Programs
    {
        [Benchmark]
        public void runGetList(){
            DataProvider dp =new DataProvider();
            var lists = dp.getATMList();
            var count = 0;
            foreach(var atm in lists){
                if(atm.Brand == "BrandA") {
                    Console.WriteLine(atm.Name );
                    ++ count;
                }
                if (count == 100){
                    break;
                }
            }
        }
        [Benchmark]
        public void runGetListByYield(){
            DataProvider dp =new DataProvider();
            var lists = dp.getATMListYield();
            int count = 0;
            foreach(var atm in lists){
                if(atm.Brand == "BrandA") {
                    Console.WriteLine(atm.Name );
                    ++ count;
                }
                if (count == 100){
                    break;
                }
            }
        }
        public static void Main(string[] args)
        {
             var summary = BenchmarkRunner.Run<Programs>();      
        }

      
    }
}

DataProvider.cs

using System;
using System.Linq;
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Diagnosers;

namespace IQueryableIEnumerable
{
    public class DataProvider {
        public IEnumerable<ATM> getATMList(){
            List<ATM> atms = new List<ATM>();
            for(var i=0; i< 10000; ++i){
                atms.Add(new ATM (){
                    Id = i,
                    Name = "Atm" + i,
                    Brand =  getBrand()
                });
            }
            return atms;
        }
        public IEnumerable<ATM> getATMListYield(){
            List<ATM> atms = new List<ATM>();
            int count = 0;
            for(var i=0; i< 10000; ++i){
                yield return new ATM (){
                    Id = i,
                    Name = "Atm" + i,
                    Brand =  getBrand()
                } ;
            }
            yield break;
        }
        private string getBrand(){
            Random rd = new Random();
            int count = rd.Next(100);
            if (count >= 50) return "BrandA";
            return "BrandB";
        }
    }
}

ATM.cs

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IQueryableIEnumerable
{
    public class ATM {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Brand {get;set;}      
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/815309.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何压缩MP4视频?学会这样压缩很简单

怎么压缩MP4视频大小呢&#xff1f;如果需要将视频存储在手机或平板电脑等设备上&#xff0c;通常也需要将视频大小压缩到适当的大小&#xff0c;以节省存储空间。此时&#xff0c;可以根据设备的存储容量和需要存储的其他文件来选择视频压缩的大小。很多小伙伴不知道怎么压缩视…

24考研数据结构-第三章:栈和队列

目录 第三章 栈和队列3.1栈&#xff08;stack&#xff09;3.1.1栈的基本概念栈的基本概念知识回顾 3.1.2 栈的顺序存储上溢与下溢栈的顺序存储知识回顾 3.1.3栈的链式存储链栈的基本操作 3.2队列&#xff08;Queue&#xff09;3.2.1队列的基本概念3.2.2队列的顺序存储结构3.2.2…

Python基础教程:Socket网络编程

网络编程是指编写程序使其能够通过网络连接与其他计算机进行通信。Python 作为一种强大的脚本语言&#xff0c;也提供了丰富的库来支持网络编程&#xff0c;如 socket、asyncio、http.client 等。在这篇教程中&#xff0c;我们将介绍如何使用 socket 库实现简单的网络编程。 1…

基于react18+hooks通用全局手机端弹框组件

RcPop 基于react18.x hooks自定义msg/alert/dialog/model/toast弹框组件 基于react18 hook开发全局通用mobile弹层组件。整合了msg/alert/dialog/toast及android/ios等弹窗效果。支持**20**参数、组件式函数式两种调用方式。 引入弹窗组件 在需要使用到弹窗的页面引入组件。 …

Linux - 添加普通用户为信任用户

1.添加用户 在Linux系统中&#xff0c;可以使用以下步骤添加用户&#xff1a; 打开终端并以root用户身份登录 输入以下命令以创建新用户&#xff08;请将username替换为您想要创建的用户名&#xff09;&#xff1a; adduser username 设置该用户的密码&#xff0c;使用以下命…

MySQL报错:Row size too large。

项目场景&#xff1a; mysql添加varchar字段 问题描述 mysql表添加一个varchar类型的字段&#xff0c;执行保存时报错&#xff1a;Row size too large. The maximum row size for the used table type, not counting BLOBs, is 6553 巴拉巴拉 原因分析&#xff1a; 行数据大…

「2024」预备研究生mem- 0730 逻辑模考

逻辑题记录&#xff1a; 前真后假&#xff0c;前假后真 削弱&#xff0c;前者更强 前假后假 是支持

迅为iTOP-LS3A5000开发板+银河麒麟操作系统

硬件准备 1.M.2.ssd硬盘&#xff08;最好大于等于128G&#xff09;&#xff1b; 2.迅为LS3A5000开发板&#xff1b; 3.U盘&#xff08;需大于8g&#xff09;&#xff0c;制作启动盘使用&#xff1b; 4.hdmi显示器&#xff1b; 5.搭载linux环境的计算机。 安装步骤 1 制作…

聚焦甲烷循环,宏基因组分析项目再创新!

甲烷&#xff0c;化学式CH4&#xff0c;在自然界分布很广&#xff0c;是最简单的有机物&#xff0c;也是最简单的烃。但同时也是一种重要的温室气体&#xff0c;是一种仅次于二氧化碳的强大温室气体&#xff0c;对环境和全球变化具有重大影响&#xff0c;其导致全球变暖潜力是C…

运动带哪种耳机比较好、最好用的运动耳机排名

作为一位热爱运动的达人&#xff0c;每天固定时间出门跑步已经成为我的必修课程。关于坚持锻炼的好处&#xff0c;我想不用多说&#xff0c;懂得人自然懂。然而&#xff0c;无论多么享受独自奔跑的感觉&#xff0c;总会有一种孤单寂寞的情绪袭上心头。相信经常跑步的朋友们都深…

如何部署Redis哨兵与集群

目录 一、Redis数据库 二、Redis哨兵模式 三、部署Redis哨兵 第一步 关闭防火墙和安全机制 第二步 修改Redis配置文件 第三步 开启Master主节点 第四步 查看哨兵信息 四、如何部署Redis集群 第一步 创建不同端口节点的目录 第二步 创建脚本文件 第三步 赋权并执行脚…

vscode设置远程登录和免密登录

首先&#xff0c;我们去官网下载VScode 安装过程比较简单&#xff0c;大家自行安装即可&#xff0c;注意建议安装在除C盘外的其他盘中。 安装完成后&#xff0c;打开我们下载好的VScode&#xff0c;点击左侧的Extensions选项&#xff0c;搜索Remote&#xff0c;Install第一项R…

【设计模式——学习笔记】23种设计模式——代理模式Proxy(原理讲解+应用场景介绍+案例介绍+Java代码实现)

介绍 基础介绍 代理模式为一个对象提供一个代理对象&#xff0c;以控制对这个对象的访问。即通过代理对象访问目标对象&#xff0c;这样做的好处是&#xff1a;可以在不修改目标对象代码的基础上&#xff0c;增强额外的功能操作&#xff0c;即扩展目标对象的功能被代理的对象…

Day06-作业(MySQL)

备注&#xff1a;本次作业最终需要提交的是对应的SQL语句。 软件安装&#xff1a;安装数据库可视化工具Navicat Navicat下载&#xff0c;提取码&#xff1a;5555https://pan.baidu.com/s/1GtKdXu9Tx0G3ejgSwKVWZg 作业1&#xff1a;参照资料中提供的页面原型及需求描述&#x…

项目中使用过的线程池ThreadPoolTaskExecutor

创建线程池的实例应用 package com.youming.shuiku.datacenter.provider.utils;import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.ThreadPoolExecutor;Slf4j public class AsyncMana…

UnixBench 5.1.3 银河麒麟桌面操作系统V10 (SP1) ARM64 aarch64 图形性能测试 2d 3d, glmark2 3d测试

编译 安装libgl sudo apt install libgl-dev yeqiangyeqiang-greatwall:~/Downloads/UnixBench$ sudo apt install libgl-dev [sudo] yeqiang 的密码&#xff1a; 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 下列软件包…

安卓耗电量分析

这里写自定义目录标题 耗电原因分析分析类型 生成分析数据batterystats操作步骤:生成report报告 battery-historian手动编译安装容器安装内容解析 耗电原因分析 下文有阐述&#xff0c;很详细 https://www.cnblogs.com/SA226343/p/6047543.html https://www.cnblogs.com/mytec…

美颜SDK开发指南:优化直播人像表现

在当今社交媒体和直播平台的流行趋势下&#xff0c;越来越多的用户渴望在直播中展现更加自信和美丽的一面。本文将探讨美颜SDK的开发指南&#xff0c;介绍其优化直播人像表现的重要性以及关键的技术要点。 一、用户为什么离不开美颜&#xff1f; 美颜SDK作为一种集成在直播应用…

javascript运算符与流程控制

文章和代码已经归档至【Github仓库&#xff1a;https://github.com/timerring/front-end-tutorial 】或者公众号【AIShareLab】回复 javascript 也可获取。 文章目录 运算符的分类算数运算符浮点数的精度问题 递增和递减运算符比较运算符逻辑运算符短路运算&#xff08;逻辑中断…

报表工具有哪些?奥威BI+方案,快速搞定数据分析

报表工具有很多&#xff0c;如Excel、 Tableau、Power BI、帆软BI、思迈特BI等都是中国企业常用的报表工具&#xff0c;但要说能够成熟使用“BI方案”&#xff0c;更快地完成部署&#xff0c;推动企业大数据分析的却寥寥无几。“奥威BI方案”&#xff0c;低风险、高效率、高性价…