ASP.NET Core高效管理字符串集合

我们在开发 Web 项目时经常遇到需要管理各种来源的字符串集合(例如HTTP 标头、查询字符串、设置的值等)的情况。合理的管理这些字符串集合不仅可以减少出bug的几率,也能提高应用程序的性能。ASP.NET Core 为我们提供了一种特殊的只读结构体 StringValues,它旨在高效处理多个字符串值,使用单个内部对象来表示null、一个或多个字符串。 下面我们来简单的探讨一下StringValues

Tip:以下文章以管理HTTP 标头的字符串集合为例来讲解,其他来源的字符串集合类似。

一、传统方式

对于字符串集合的管理,我们会想到使用数组来存储每个标头关键字的多个值。 这种方法看起来简单易懂,代码也容易编写,但是却会带来性能和字符串管理的复杂性问题。当我们使用数组存储标头值时,就会遇到内存分配增加的问题。 即使在不必要的情况下,存储单个值也需要分配一个数组,这样就出现内了存浪费,那么在大流量网络应用中就会出现很明显的性能问题。
用一个例子来讲解以下。在程序中我们添加一个 HeaderManager 类,这个类用来存储HTTP标头,代码如下:

public class HeaderManager
{private readonly Dictionary<string, string[]> _headers = [];public void AddHeader(string key, params string[] values){if (_headers.TryGetValue(key, out var existingValues)){var newValues = new string[existingValues.Length + values.Length];existingValues.CopyTo(newValues, 0);values.CopyTo(newValues, existingValues.Length);_headers[key] = newValues;}else{_headers[key] = values;}}
}

在上面的代码中,我们声明类型为 Dictionary<string, string[]>的私有字段 _headers,我们又定义了一个 AddHeader方法,它接收一个字符串类型的键key以及一个使用 params关键字标记的数量可变的字符串值values。 接着我们使用 TryGetValue方法来检查字典 _headers中是否已包含指定的键,如果键存在就会创建一个新数组将现有值和新值合并起来,最后我们用合并后的数组更新字典。
传统方式使用 Dictionary<string, string[]>类型的变量来存储标头值,当添加新值时分配一个新的数组,然后复制现有值并添加新值。这种方法虽然简单明了,但频繁调整数组大小会导致内存分配增加从而造成性能问题。

二、使用 NameValueCollection

NameValueCollection允许我们在单个键下存储多个值。我们来修改一下前一小节的代码:

public class HeaderManager
{private readonly NameValueCollection _headers = [];public void AddHeader(string key, params string[] values){foreach (var value in values){_headers.Add(key, value);}}
}

在代码中,我们声明一个类型为 NameValueCollection的字段 _headers,在AddHeader方法中遍历 values数组,并将其添加到具有指定键的 _headers 集合中。NameValueCollection简化了标头管理,但由于内部要处理数组,因此也需要分配更多内存。

三、使用 StringValues

在 ASP.NET Core 中的许多核心组件和中间件都使用StringValues来管理字符串集合。StringValuesstruct类型(值类型),值类型是存储在堆栈中的,因此它与堆分配相比值类型的分配和取消分配速度更快,这又减少了内存的分配,进而降低了对垃圾回收的需求。StringValues对象可以存储null值、单个字符串和字符串数组。它使用单个对象来存储值,可帮助我们的项目减少内存分配,从而提高应用程序性能。 下面我们一起来看一下如何使用吧。

3.1 安装

要使用 StringValues就要安装Primitives软件包,在命令行输入如下代码即可安装:

dotnet add package Microsoft.Extensions.Primitives
3.2 使用
  1. 包含单个字符串的 StringValues

    StringValues singleValue = new StringValues("value1");
    

    在上面代码中,我们使用了StringValues的构造函数传入字符串初始化 StringValues对象。这个构造函数创建的对象可以有效地存储单个字符串而不需分配数组。

  2. 让我们用字符串数组初始化 StringValues对象:

    StringValues multipleValues = new StringValues(new[] { "value1", "value2" });
    

    在上面代码中,我们使用 StringValues的数组构造函数,用字符串数组进行初始化。 当我们需要处理字符串集合时就可以使用这个构造函数。

  3. 使用空值或 null 值初始化 StringValues对象:

    StringValues emptyValue = new StringValues();
    StringValues nullValue = new StringValues((string)null);
    

    在上面代码中,我们使用空值和 null 值初始化 StringValues构造函数。 这个构造函数可处理无值的情况,确保 StringValues能管理空或 null 输入。

3.3 StringValues 的隐式转换以及逗号分隔字符串表示法

StringValues支持从单个字符串或字符串数组的隐式转换,方便我们初始化。当StringValues包含多个字符串时,它可以将它们表示为单个逗号分隔的字符串,代码如下:

StringValues implicitSingle = "value1";
Console.WriteLine($"隐式转换单个字符串: {implicitSingle}");
StringValues implicitMultiple = new[] { "value1", "value2" };
Console.WriteLine($"隐式转换多个字符串集合 : {implicitMultiple}");
StringValues values = new StringValues(new[] { "value1", "value2" });
Console.WriteLine($"逗号分隔值: {values}");

输出结果如下:
在这里插入图片描述
在上面代码中,当单个字符串被隐式转换为 StringValues`` 时它会直接显示该字符串,对于字符数组会转换为 StringValues```对象,并以逗号分隔列表的形式显示。

3.4 StringValues 的使用

我们修改一开始编写的HeaderManager类,将这个类修改为使用StringValues实现管理字符串集合,代码如下:

public class HeaderManager
{private readonly Dictionary<string, StringValues> _headers = new();public void AddHeader(string key, params string[] values){if (_headers.TryGetValue(key, out var existingValues)){_headers[key] = StringValues.Concat(existingValues, new StringValues(values));}else{_headers[key] = new StringValues(values);}}
}

在上面代码中,我们声明一个 类型为 Dictionary<string, StringValues>的字段 _headers。 然后使用TryGetValue检查_headers字典中是否已包含键,如果键存在就使用 StringValues.Concat方法将新值连接到现有的 StringValues对象上,否则创建一个新的 StringValues实例并将其添加到字典中。

四、总结

在开发 Web 项目时,管理不同来源的字符串集合(如 HTTP 标头、查询字符串、设置值等)至关重要。传统方法使用数组或 NameValueCollection 来管理这些字符串,但这些方法存在性能和内存管理问题。特别是数组的频繁调整会导致不必要的内存分配,影响性能。
ASP.NET Core 提供了 StringValues 结构体,作为更高效的解决方案。StringValues 是一个只读的值类型,支持单个字符串、字符串数组以及空值(null)。它通过减少内存分配和垃圾回收需求,提升了应用程序性能。与传统方法相比,StringValues 能更有效地处理字符串集合,避免了内存浪费。
使用 StringValues 可以显著优化管理字符串集合的性能,特别是在高流量网络应用中,其优势更加明显。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C/C++实现植物大战僵尸(PVZ)(打地鼠版)

&#x1f680;欢迎互三&#x1f449;&#xff1a;程序猿方梓燚 &#x1f48e;&#x1f48e; &#x1f680;关注博主&#xff0c;后期持续更新系列文章 &#x1f680;如果有错误感谢请大家批评指出&#xff0c;及时修改 &#x1f680;感谢大家点赞&#x1f44d;收藏⭐评论✍ 游戏…

【数据结构】字符串与JSON字符串、JSON字符串及相应数据结构(如对象与数组)之间的相互转换

前言&#xff1a; 下面打印日志用的是FastJSON依赖库中的 Log4j2。依赖&#xff1a; <!-- Alibaba Fastjson --> <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.80</version> …

[Redis] Redis中的set和zset类型

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

OpenCV运动分析和目标跟踪(1)累积操作函数accumulate()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 将一个图像添加到累积图像中。 该函数将 src 或其部分元素添加到 dst 中&#xff1a; dst ( x , y ) ← dst ( x , y ) src ( x , y ) if mask…

mysql笔记8(多表查询)

文章目录 1. union联合查询可能会用到去重操作 2. inner join 内连接3. left join 左连接4. right join 右连接5. cross join 交叉连接6. natural join 自然连接natural left join 自然左连接natural right join 自然右连接自然连接的两张表没有同名字段怎么办&#xff1f; 7. …

自定义EPICS在LabVIEW中的测试

继续上一篇&#xff1a;LabVIEW中EPICS客户端/服务端的测试 变量定义 You can use CaLabSoftIOC.vi to create new EPICS variables and start them. CA Lab - LabVIEW (Realtime) EPICS INPUT: PV set Cluster-array of names, data types and field definitions to crea…

VMware Fusion虚拟机Mac版 安装Ubuntu操作系统教程

Mac分享吧 文章目录 下载镜像地址&#xff1a;[www.macfxb.cn](http://www.macfxb.cn)一、Ubuntu安装完成&#xff0c;软件打开效果二、Mac中安装Ubuntu虚拟机1️⃣&#xff1a;下载镜像2️⃣&#xff1a;创建虚拟机3️⃣&#xff1a;虚拟机设置4️⃣&#xff1a;虚拟机安装5️…

3.信号量与互斥量

队列:用来传递数据 如果不想传递数据,只是"通知"呢? 这个时候,我们就可以使用"信号量","信号量"的本质:item_size等于 0 的队列 信号量里面有什么呢? 1.一个计数值 2.一个"队伍",就是一个链表:用来记录等待的对应信号量的任务 …

OpenGL笔记二十一之几何类设计

OpenGL笔记二十一之几何类设计 —— 2024-09-16 下午 bilibili赵新政老师的教程看后笔记 code review! 文章目录 OpenGL笔记二十一之几何类设计1.运行1.1.立方体运行1.2.球体运行 2.几何类搭建1.立方体分析2.球体分析3.图片资源文件4.关键实现4.1.geometry.h4.2.geometry.cpp…

PCL 曲线点云提取

文章目录 一、简介二、实现代码三、实现效果参考文献一、简介 提取曲线点云的方法主要分为两种:参数化与非参数化,其中参数化是指事先直线曲线的形状,反之,非参数化则是不依赖与曲线的参数,通常是一种聚类的行为。这里我们采用非参数方法(TriplClust),将点集划分为一个未…

Redis的配置与优化

目录 一、关系数据库与非关系型数据库 1.1、关系型数据库 1.2、非关系型数据库 1.3、关系型数据库和非关系型数据库区别 数据存储方式不同 扩展方式不同 对事务性的支持不同 1.4、非关系型数据库产生背景 二、Redis简介 2.1、Redis优点 2.2、Redis为什么这么快 三、…

如何编写智能合约——基于长安链的Go语言的合约开发

场景设计&#xff1a;文件存证系统 在数字化时代&#xff0c;文件存证和版本追踪变得越来越重要。设想一个场景&#xff1a;在一个法律事务管理系统中&#xff0c;用户需要提交和管理各种文件的版本记录&#xff0c;以确保每个文件在不同时间点的状态可以被准确追踪。文件可能经…

数据结构之栈(python)

栈&#xff08;顺序栈与链栈&#xff09; 1.栈存储结构1.1栈的基本介绍1.2进栈和出栈1.3栈的具体实现1.4栈的应用例一例二例三 2.顺序栈及基本操作&#xff08;包含入栈和出栈&#xff09;2.1顺序栈的基础介绍2.2顺序栈元素入栈2.3顺序栈元素出栈2.4顺序栈的表示和实现 3.链栈及…

【腾讯云】AI驱动TDSQL-C Serveress 数据库技术实战营-如何是从0到1体验电商可视化分析小助手得统计功能,一句话就能输出目标统计图

欢迎来到《小5讲堂》 这是《腾讯云》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 背景效果图流程图创建数据库基本信息数据库配置设置密码控制台开启…

Java-数据结构-二叉树-习题(三)  ̄へ ̄

文本目录&#xff1a; ❄️一、习题一(前序遍历非递归)&#xff1a; ▶ 思路&#xff1a; ▶ 代码&#xff1a; ❄️二、习题二(中序遍历非递归)&#xff1a; ▶ 思路&#xff1a; ▶ 代码&#xff1a; ❄️三、习题三(后序遍历非递归)&#xff1a; ▶ 思路&#xff1a; …

一款源码阅读的插件

文章目录 进度汇报功能预览添加高亮标记高亮风格设置笔记颜色设置数据概览高亮数据详情 结尾 进度汇报 之前提到最近有在开发一个源码阅读的IDEA插件&#xff0c;第一版已经开发完上传插件市场了&#xff0c;等官方审批通过就可以尝鲜了。插件名称&#xff1a;Mark source cod…

算法之搜索--最长公共子序列LCS

最长公共子序列&#xff08;longest common sequence&#xff09;:可以不连续 最长公共子串&#xff08;longest common substring&#xff09;&#xff1a;连续 demo for (int i 1;i<lena;i){for (int j 1;j<lenb;j){if(a[i-1]b[j-1]){dp[i][j]dp[i-1][j-1]1;}el…

java企业办公自动化OA

技术架构&#xff1a; sshjbpm 功能描述&#xff1a; 用户管理&#xff0c;岗位管理&#xff0c;部门管理&#xff0c;权限管理&#xff0c;网上交流&#xff0c;贴吧&#xff0c;审批流转。权限管理是树状结构人性化操作&#xff0c;也可以用作论坛。 效果图&#xff1a;

三维手势 第一人称 汽车驾驶 handpose 3D RGB 单目相机手势识别 手势检测 手势3D建模 三维建模

三维手势 第一人称 汽车驾驶 handpose 3D RGB 单目相机手势识别 手势检测 手势3D建模 三维建模 第一人称汽车安全驾驶 &#xff1a;三维手势建模 RGB 单目相机手势识检测 手势3D建模 咨询合作 DataBall 项目&#xff0c;欢迎加以下微信。 助力快速掌握数据集的信息和使用方式…

OpenAI API key not working in my React App

题意&#xff1a;OpenAI API 密钥在我的 React 应用中不起作用 问题背景&#xff1a; I am trying to create a chatbot in my react app, and Im not able to generate an LLM powered response. Ive been studying documentation and checking out tutorials but am unable …