在C#中如何减少新字符串的产生(c#去除字符串中的数字)

在C#中如何减少新字符串的产生(c#去除字符串中的数字)

编码文章call10242025-02-01 3:40:2419A+A-

前言

近日,偶然看见一段代码,在项目中,也是这般用法。然而,实则此般用法当下是欠佳的。且先瞧瞧这一段代码。

public string HandlerActionName2(string actionName)
{
	if (actionName.EndsWith("Async", StringComparison.Ordinal))
	{
		actionName = actionName.Substring(0, actionName.Length - 5); //这里用Substring真的合适不? 
	}
	return actionName;
}

在对 HandlerActionName2 进行调用时,倘若依旧会生成新的字符串,那么此处是否真的有必要产生新字符串呢?在.Net Core 2.1 中提供了 ReadOnlySpan ,将其运用于此能够减少新字符串的创建。

public ReadOnlySpan HandleActionName(ReadOnlySpan actionName)
{
	if (actionName.EndsWith("Async", StringComparison.Ordinal))
	{
		//使用ReadOnlySpan的Slice进行切片,这个没有产生新的字符串
		actionName = actionName.Slice(0, actionName.Length - 5); 
	}
	return actionName;
}

性能基准测试

using System;
using BenchmarkDotNet.Attributes;

namespace CSharpBenchmarks.StringTest
{
	[MemoryDiagnoser]
	[DisassemblyDiagnoser(printSource: true)]
	public class StringToReadOnlySpan
	{
		/// 
		/// 分别执行1024次和202048次
		/// 
		[Params(1024, 2048)]
		public int Times { get; set; }

		/// 
		///这里有两个字符串,用于测试
		/// 
		[Params("TestAsync", "Test")]
		public string Names { get; set; }

		[Benchmark]
		public int ReadOnlySpanTest()
		{
			int count = 0;
			for (int i = 0; i < Times; i++)
			{
				count += HandleActionName(Names).Length;
			}
			return count;
		}

		[Benchmark(Baseline = true)]
		public int StringTest()
		{
			int count = 0;
			for (int i = 0; i < Times; i++)
			{
				count += HandlerActionName2(Names).Length;
			}
			return count;
		}

		public ReadOnlySpan HandleActionName(ReadOnlySpan actionName)
		{
			if (actionName.EndsWith("Async", StringComparison.Ordinal))
			{
				//使用ReadOnlySpan的Slice进行切片,这个没有产生新的字符串
				actionName = actionName.Slice(0, actionName.Length - 5);
			}
			return actionName;
		}

		public string HandlerActionName2(string actionName)
		{
			if (actionName.EndsWith("Async", StringComparison.Ordinal))
			{
        //这里用Substring真的合适不? 
				actionName = actionName.Substring(0, actionName.Length - 5); 
			}
			return actionName;
		}
	}
}

笔记本执行结果:

台式机执行结果:

根据测试结果:

1. 如果字符串中没有Async结尾的话,使用String比ReadOnlySpan比快35%和100%之间,具体取决于硬件了.

2. 如果字符中是以Async结尾的话,ReadOnlySpan的Slice只是String.SubString的25%和29%,换而言之,SubString比Slice耗时多了3倍,因为Slice是没有产生新字符串,这一点从GC 0代回收次数也可以看到.减少内存分配,降低触发GC回收的次数.

个人能力有限,如果您发现有什么不对,请私信我

如果您觉得对您有用的话,可以点个赞或者加个关注,欢迎大家一起进行技术交流

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4