当前位置: 首页 > news >正文

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 可以显著优化管理字符串集合的性能,特别是在高流量网络应用中,其优势更加明显。

相关文章:

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

我们在开发 Web 项目时经常遇到需要管理各种来源的字符串集合&#xff08;例如HTTP 标头、查询字符串、设置的值等&#xff09;的情况。合理的管理这些字符串集合不仅可以减少出bug的几率&#xff0c;也能提高应用程序的性能。ASP.NET Core 为我们提供了一种特殊的只读结构体 S…...

vm-tools的卸载重装,只能复制粘贴,无法拖拽文件!

开始 ubuntu22.04 LTSVMwareTools-10.3.25-20206839.tar.gzVMware Workstation 17 Pro 各种该尝试的配置都尝试了,比如: 1.开启复制粘贴拖拽; 2.VMware Tools拖拽失效; 3.解决VMware无法拖拽. 均没有奏效. 安装过程报错, 报错异常: The installation of VMware Tools 10.3.25…...

Docker 容器网络技术

Docker 容器网络技术 一、概述 Docker 容器技术在微服务架构和云原生应用中扮演着重要角色。容器的轻量化和快速启动特性&#xff0c;使得它们成为现代应用部署的首选。然而&#xff0c;容器的网络连接和管理是一个复杂的问题&#xff0c;尤其是当涉及到容器间通信时。Docker…...

C++ 起始帧数、结束帧数、剪辑视频

C 指定起始帧数、结束帧数、 剪辑视频 C 无法直接用H264&#xff0c;只能用avi编码格式 #include <iostream> #include <opencv2/opencv.hpp>int main() {// 读取视频&#xff1a;创建了一个VideoCapture对象&#xff0c;参数为摄像头编号std::string path &quo…...

【项目一】基于pytest的自动化测试框架———解读requests模块

解读python的requests模块 什么是requests模块基础用法GET与POST的区别数据传递格式会话管理与持久性连接处理相应结果应对HTTPS证书验证错误处理与异常捕获 这篇blog主要聚焦如何使用 Python 中的 requests 模块来实现接口自动化测试。下面我介绍一下 requests 的常用方法、数…...

升级Ubuntu内核的几种方法

注意&#xff1a; Ubuntu主线内核由 Ubuntu 内核团队提供&#xff0c;用于测试和调试目的。 它们不受支持且不适合生产使用。 仅当它们可以解决当前内核遇到的关键问题时&#xff0c;才应该安装它们。 1、手动下载deb文件升级内核 来源&#xff1a;kernel.ubuntu.com/main…...

Android绘制靶面,初步点击位置区域划分取值测试

自定义View&#xff1a; public class TargetView extends View {private Paint paint;private int[] radii {100, 250, 400, 550, 700}; // 五个圆的半径private int numberOfSegments 8;private int[][] regionValues; // 存储每个区域的值public TargetView(Context cont…...

【SpringBoot】调度和执行定时任务--Quartz(超详细)

Quartz 是一个功能强大的任务调度框架&#xff0c;广泛用于在 Java 应用程序中定时执行任务&#xff0c;同时它支持 Cron 表达式、持久化任务、集群等特性。以下是 Quartz 的详细使用教程&#xff0c;包括安装、基本概念、简单示例和高级功能。 1. 安装 Quartz 首先&#xff…...

低代码开发平台系统架构概述

概述 织信低代码开发平台&#xff08;产品全称&#xff1a;织信Informat&#xff09;是一款集成了应用设计、运行与管理的综合性平台。它提供了丰富的功能模块&#xff0c;帮助用户快速构建、部署和维护应用程序。织信低代码平台通过集成丰富的功能模块&#xff0c;为用户提供…...

源码编译llama.cpp 、ggml 后端启用自定义BLAS加速

源码编译llama.cpp 、ggml 后端启用自定义BLAS加速 我在llama.cpp 官网上提交了我的解决方案&#xff1a;How to setup OpenBlas on windows? #625 GGML 官网 https://github.com/ggerganov/ggml/issues/959 windows on arm 编译 llama.cpp 、ggml 后端启用自定义BLAS加速 …...

glb数据格式

glb数据格式 glb 文件格式只包含一个glb 文件&#xff0c;文件按照二进制存储&#xff0c;占空间小 浏览 浏览glb工具的很多&#xff0c;ccs&#xff0c;3D查看器等都可以&#xff0c;不安装软件的话用下面网页加载就可以&#xff0c;免费 glTF Viewer (donmccurdy.com) glb…...

手语识别系统源码分享

手语识别检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …...

Oracle 数据库部署与实施

文章目录 1. macOS 上部署 Oracle 数据库通过 Docker 在 macOS 上部署 2. Linux 上部署 Oracle 数据库直接在 Linux 上部署通过 Docker 在 Linux 上部署 3. Windows 上部署 Oracle 数据库4. 使用 Docker 部署 Oracle 数据库前提条件拉取 Oracle 数据库 Docker 镜像运行 Oracle …...

【Python】 ast.literal_eval 与 eval

一、背景 我在在编写管理后台的过程中&#xff0c;遇到一个小问题&#xff0c;是关于用户名的存储和解码。用户名以base64编码的形式存储在 MySQL 数据库中&#xff0c;并且还保留了b这样的形式&#xff0c;具体为什么要这样存我也不知道,可能是因为有些特殊字符无法直接存储。…...

Java 入门指南:JVM(Java虚拟机)垃圾回收机制 —— 新一代垃圾回收器 ZGC 收集器

文章目录 垃圾回收机制垃圾收集器垃圾收集器分类ZGC 收集器ZGC 的性能优势复制算法指针染色读屏障 ZGC 的工作过程Stop-The-World 暂停阶段并发阶段 垃圾回收机制 垃圾回收&#xff08;Garbage Collection&#xff0c;GC&#xff09;&#xff0c;顾名思义就是释放垃圾占用的空…...

基于 K8S kubernetes 的常见日志收集方案

目录 1、日志对我们来说到底重不重要&#xff1f; 2、常见的日志收集方案 2.1 EFK 2.2 ELK Stack 2.3 ELKfilebeat 2.4 其他方案 2、elasticsearch组件介绍 3、filebeat组件介绍 3.1 filebeat和beat关系 3.2 filebeat是什么&#xff1f; 3.3 Filebeat工作原理 3.4 …...

Unity3D 小案例 像素贪吃蛇 02 蛇的觅食

Unity3D 小案例 像素贪吃蛇 第二期 蛇的觅食 像素贪吃蛇 食物生成 在场景中创建一个 2D 正方形&#xff0c;调整颜色&#xff0c;添加 Tag 并修改为 Food。 然后拖拽到 Assets 文件夹中变成预制体。 创建食物管理器 FoodManager.cs&#xff0c;添加单例&#xff0c;可以设置…...

【sgCreateCallAPIFunction】自定义小工具:敏捷开发→调用接口方法代码生成工具

<template><div :class"$options.name" class"sgDevTool"><sgHead /><div class"sg-container"><div class"sg-start"><div style"margin-bottom: 10px">调用接口方法定义列表</div…...

京东商品详情的 API 探秘与应用

在当今数字化的商业世界中&#xff0c;获取准确而详细的商品信息对于开发者、商家以及消费者都具有至关重要的意义。京东作为国内领先的电商平台之一&#xff0c;提供了丰富的商品资源和强大的 API 接口&#xff0c;让我们能够轻松获取京东商品的详情信息。本文将带你深入了解如…...

功能测试干了三年,快要废了。。。

8年前刚进入到IT行业&#xff0c;到现在学习软件测试的人越来越多&#xff0c;所以在这我想结合自己的一些看法给大家提一些建议。 最近聊到软件测试的行业内卷&#xff0c;越来越多的转行和大学生进入测试行业&#xff0c;导致软件测试已经饱和了&#xff0c;想要获得更好的待…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...