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

news2024/11/24 18:47:48

我们在开发 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.coloradmin.cn/o/2135322.html

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

相关文章

网络基础,协议,OSI分层,TCP/IP模型

网络的产生是数据交流的必然趋势&#xff0c;计算机之间的独立的个体&#xff0c;想要进行数据交互&#xff0c;一开始是使用磁盘进行数据拷贝&#xff0c;可是这样的数据拷贝效率很低&#xff0c;于是网络交互便出现了&#xff1b; 1.网络是什么 网络&#xff0c;顾名思义是…

工业网关在工厂数据采集中的核心作用-天拓四方

随着工业4.0时代的到来&#xff0c;工厂设备数据采集的重要性日益凸显。其中&#xff0c;工业网关以其独特的功能和优势&#xff0c;在工厂数据采集系统中发挥着核心作用。本文旨在深入探讨工业网关在工厂数据采集中的关键作用&#xff0c;以及它是如何助力工厂实现智能化、高效…

高性能编程:无锁队列

目录 1.无锁队列 1.1.1 阻塞&#xff08;Blocking&#xff09; 1.1.2 无锁&#xff08;Lock-Free&#xff09; 1.1.3 无等待&#xff08;Wait-Free&#xff09; 1.2 队列 1.2.1 链表实现的队列 1.2.2 数组实现的队列 1.2.3 混合实现的队列 1.3 多线程中的先进先出数据…

打破瓶颈:搭贝低代码平台助力企业数字化转型

在当今快速变化的商业环境中&#xff0c;越来越多的企业认识到数字化转型的重要性。然而&#xff0c;很多企业在追求数字化的过程中却遇到各种障碍&#xff0c;无论是信息管理的混乱、软件使用的低效&#xff0c;还是应对市场变化的迟缓&#xff0c;这些问题都在消耗企业的资源…

React学习笔记(1.0)

在使用vite创建react时&#xff0c;有一个语言选项&#xff0c;就是typescript-SWC&#xff0c;这里介绍一下SWC。 SWC&#xff1a;可扩展的Rust的平台&#xff0c;用于下一代快速开发工具&#xff0c;SWC比Babel快20倍。 简单来说&#xff0c;就是用于格式转换的&#xff0c…

反向沙箱的功能特点

在这个信息化飞速发展的时代&#xff0c;企业的数据安全面临着前所未有的挑战。员工的无意操作、恶意软件的潜伏、甚至是敌对势力的网络攻击&#xff0c;都可能成为企业数据安全的致命威胁。深信达SPN反向沙箱为您筑起了一道坚不可摧的数据安全防线&#xff01; 来百度APP畅享高…

《Python青少年趣味编程108例》书籍介绍

文章目录 前言为什么选择Python&#xff1f;书籍介绍文章目录配套资源 前言 在这个数字化飞速发展的时代&#xff0c;编程已经成为了一项不可或缺的技能。对于青少年而言&#xff0c;学习编程不仅能够培养逻辑思维、解决问题的能力&#xff0c;还能激发无限创意&#xff0c;让…

代码随想录刷题day32丨动态规划理论基础,509. 斐波那契数, 70. 爬楼梯, 746. 使用最小花费爬楼梯

代码随想录刷题day32丨动态规划理论基础&#xff0c;509. 斐波那契数&#xff0c; 70. 爬楼梯&#xff0c; 746. 使用最小花费爬楼梯 1.动态规划理论基础 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题…

如何实现跨站点协同管理和异地远程管理监控?

前言 随着科技进步&#xff0c;企业愈发重视智能化生产&#xff0c;它提升效率、降低成本、提高质量&#xff0c;帮助企业更好应对市场变化。对于拥有多个分散站点的大型企业&#xff0c;跨站点协同管理成为一大挑战。 在这一背景下&#xff0c;宏集物联网HMI异地远程管理和监…

SSM 传统工艺品销售网站---附源码74714

摘 要 近年来&#xff0c;信息网络迅猛推进&#xff0c;其具有灵活方便、传递消息速度快等优点&#xff0c;这一新兴媒体日渐兴盛&#xff0c;已经成为人们日常生活获取信息一个重要手段。从08开始&#xff0c;电商行业如春风吹过后的小草&#xff0c;呈现出一片蓬勃地发展态势…

yjs03——matplotlib的介绍与使用(一个图里面画折线)

import...as plt plt.figure(figsize&#xff08;宽度&#xff0c;高度&#xff09;&#xff0c;dpi清晰度) x... y... plt.plot(x,y,label"上海"&#xff0c;color“r”&#xff0c;linestyle“--”) plt.xticks(刻度ticks&#xff08;仅限数字&#xff09;&#xf…

测试2sigma离群点过滤

椭圆跑道形内部的离群点移除失败,影响拟合结果

为什么自动驾驶技术的实现离不开4G+5G多卡聚合?

如今&#xff0c;汽车制造商和零部件巨头都在研究自动驾驶相关技术。要实现汽车的自动驾驶&#xff0c;不乏相关技术与道路环境的结合和变化。但要实现这一目标&#xff0c;最重要的环节无疑是建设网络。 在4G时代&#xff0c;随着网络带宽和速度的提高&#xff0c;可以实现实…

PMP--一模--解题--51-60

文章目录 9.资源管理--职能经理--项目经理要找他沟通51、 [单选] 团队成员必须按照进度基准来完成一个复杂项目的可交付成果。但是&#xff0c;由于一些团队成员被其他职能经理分配给其他任务&#xff0c;导致项目落后。 若要将项目拉回正轨&#xff0c;项目经理应该做什么&…

软件安装攻略:EmEditor编辑器下载安装与使用

EmEditor是一款在Windows平台上运行的文字编辑程序。EmEditor以运作轻巧、敏捷而又功能强大、丰富著称&#xff0c;得到许多用户的好评。Windows内建的记事本程式由于功能太过单薄&#xff0c;所以有不少用户直接以EmEditor取代&#xff0c;emeditor是一个跨平台的文本编辑器&a…

【vuetify】v-select 无法正常显示,踩坑记录!

一、上代码 template <v-selectv-model"editedUser.userRole":items"roles"label"角色"item-value"value":rules"[rules.required]" ></v-select>script const editedUser ref({userRole: customer // 设置…

springboot老年康复中心—计算机毕业设计源码27406

摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出法&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤,采用Springboo框架建设老年康复中心信息管理系统。…

Redis运维之监控指标,性能监控,监控方式,响应慢分析

文章目录 1 Redis监控1.1 Redis监控指标1.1.1 性能指标: Performance1.1.2 内存指标: Memory1.1.3 基本活动指标&#xff1a;Basic activity1.1.4 持久性指标: Persistence1.1.5 错误指标&#xff1a;Error 1.2 监控方式1.2.1 info1.2.2 性能监控1.2.3 内存监控1.2.4 基本活动指…

警惕!尿血背后隐藏的健康危机,你不可不知的五大原因!

在这个快节奏的时代&#xff0c;健康成为了我们最宝贵的财富。然而&#xff0c;一些细微的身体信号往往被忽视&#xff0c;直到问题严重才引起重视。今天&#xff0c;我们就来聊聊一个让人不安却又必须正视的话题——尿血。当你发现尿液中混杂着红色或粉红色时&#xff0c;这不…

攻防演练篇:攻防演练场景中面临的常见加密威胁-HTTP隐蔽隧道

1 概述 在网络安全领域&#xff0c;隐蔽隧道是一种基于主流常规协议将恶意流量伪装成正常通信起到夹带偷传数据、下发控制指令等作用&#xff0c;同时对数据进行加密以最大限度的规避网络安全设备检测的传输技术。由于隐蔽隧道更容易绕过网络安全设备的检测&#xff0c;因此黑…