.net中的字符串操作性能问题由来已久,幸运的是微软推出了span<T>高性能指针操作封装工具类。这个类到底有多高的性能呢?网上传言反正很高,但是实际上在网上很难找到合适的测试实例,这让本人实在无力吐槽。经不住高性能这三个字的诱惑,本人还是了解了一番后做了几个简单样例来测试一番,下面列出几种字符串常见操作的测试代码及其运行结果。

一、String.Index 测试

             var t1 = StopWacherHelper.DoTimer(() =>
{
for (int i = ; i < count; i++)
{
str.IndexOf(subStr);
}
}); Console.WriteLine($"string.IndexOf {count} 次用时:{t1} 毫秒");
             var t2 = StopWacherHelper.DoTimer(() =>
{
var strSpan = str.AsSpan(); var subStrSpan = subStr.AsSpan(); for (int i = ; i < count; i++)
{
strSpan.IndexOf(subStrSpan);
}
}); Console.WriteLine($"Span<T>.IndexOf {count} 次用时:{t2} 毫秒");

二、String.Substring 测试

             var t1 = StopWacherHelper.DoTimer(() =>
{
for (int i = ; i < count; i++)
{
str.Substring(, str.IndexOf(subStr));
}
}); Console.WriteLine($"String.Substring {count} 次用时:{t1} 毫秒");
             var t2 = StopWacherHelper.DoTimer(() =>
{
var strSpan = str.AsSpan(); var subStrSpan = subStr.AsSpan(); var index = strSpan.IndexOf(subStrSpan); for (int i = ; i < count; i++)
{
strSpan.Slice(, strSpan.IndexOf(subStrSpan));
}
});

三、String.Split 测试

             var t1 = StopWacherHelper.DoTimer(() =>
{
for (int i = ; i < count; i++)
{
var arr = str.Split(new string[] { splitStr }, StringSplitOptions.None);
}
}); Console.WriteLine($"String.Split {count} 次用时:{t1} 毫秒");
             var t2 = StopWacherHelper.DoTimer(() =>
{
var strSpan = str.AsSpan(); var splitSapn = splitStr.AsSpan(); int m = , n = ; for (int i = ; i < count; i++)
{
List<string> arr = new List<string>(); while (true)
{
m = n;
n = strSpan.IndexOf(splitSapn);
if (n > -)
{
arr.Add(strSpan.Slice(, n).ToString());
strSpan = strSpan.Slice(n + splitSapn.Length);
}
else
{
break;
}
} }
}); Console.WriteLine($"Span<T>.Split {count} 次用时:{t2} 毫秒");

四、String.Replace 测试

             var t1 = StopWacherHelper.DoTimer(() =>
{
for (int i = ; i < count; i++)
{
str.Replace(splitStr, replaceStr);
}
}); Console.WriteLine($"String.Replace {count} 次用时:{t1} 毫秒");
             var t2 = StopWacherHelper.DoTimer(() =>
{
var strSpan = str.AsSpan(); var splitSapn = splitStr.AsSpan(); int m = , n = ; for (int i = ; i < count; i++)
{
List<string> arr = new List<string>(); while (true)
{
m = n;
n = strSpan.IndexOf(splitSapn);
if (n > -)
{
arr.Add(strSpan.Slice(, n).ToString());
strSpan = strSpan.Slice(n + splitSapn.Length);
}
else
{
break;
}
}
string.Join(replaceStr, arr);
}
}); Console.WriteLine($"Span<T>.Replace {count} 次用时:{t2} 毫秒");

  怎么样,经过上面的测试,是不是觉的Span<T>确实是名不虚传?的确,在上面几个常见场景中,Span<T>的高性能确实不同凡响,差不多是10倍的性能优势!看到这里,小伙伴们是不是觉的字符串操作全改成Span<T>就行了?那下面的两个测试会让大家看清现实,在String.Contains中表现还不如原生的。

一、String.Contains 测试

             var t1 = StopWacherHelper.DoTimer(() =>
{
for (int i = ; i < count; i++)
{
str.Contains(subStr);
}
}); Console.WriteLine($"string.Contains {count} 次用时:{t1} 毫秒");
             var t2 = StopWacherHelper.DoTimer(() =>
{
var strSpan = str.AsSpan(); var subStrSpan = subStr.AsSpan(); for (int i = ; i < count; i++)
{
strSpan.Contains(subStrSpan, StringComparison.CurrentCulture);
}
}); Console.WriteLine($"Span<T>.Contains {count} 次用时:{t2} 毫秒");

  仔细一看,不对啊,Span<T>的Contains里面有其它的大小写和语言相关的判断啊。好,那再换一个原生方法对比测试一下。

二、String.Compare 测试

             var t1 = StopWacherHelper.DoTimer(() =>
{
for (int i = ; i < count; i++)
{
string.Compare(str, subStr, true);
}
}); Console.WriteLine($"string.Compare {count} 次用时:{t1} 毫秒");
             var t2 = StopWacherHelper.DoTimer(() =>
{
var strSpan = str.AsSpan(); var subStrSpan = subStr.AsSpan(); for (int i = ; i < count; i++)
{
strSpan.Contains(subStrSpan, StringComparison.CurrentCultureIgnoreCase);
}
}); Console.WriteLine($"Span<T>.Contains {count} 次用时:{t2} 毫秒");

  还是被反杀了,这说明Span<T>的这个Contains方法可能真的只能在某些地方才能用,不然性能反而会有所下降。

如果对上述感兴趣,可以点击这里下载测试源码,更多请点击左下角的推荐,谢谢~

span<T>之高性能字符串操作实测的更多相关文章

  1. 如何使用T-SQL备份还原数据库及c#如何调用执行? C#中索引器的作用和实现。 jquery控制元素的隐藏和显示的几种方法。 localStorage、sessionStorage用法总结 在AspNetCore中扩展Log系列 - 介绍开源类库的使用(一) span<T>之高性能字符串操作实测

    如何使用T-SQL备份还原数据库及c#如何调用执行? 准备材料:Microsoft SQL Server一部.需要还原的bak文件一只 一.备份 数据库备份语句:user master backup ...

  2. 【超值分享】为何写服务器程序需要自己管理内存,从改造std::string字符串操作说起。。。

    服务器程序为何要进行内存管理,管中窥豹,让我们从string字符串的操作说起...... new/delete是用于c++中的动态内存管理函数,而malloc/free在c++和c中都可以使用,本质上 ...

  3. Python数据科学手册-Pandas:向量化字符串操作、时间序列

    向量化字符串操作 Series 和 Index对象 的str属性. 可以正确的处理缺失值 方法列表 正则表达式. Method Description match() Call re.match() ...

  4. 如何手动实现C语言中的字符串操作

    学了字符串操作,很多人也许学了大概知道怎么用,但是太久没用就忘了,恰恰这是找软件工程师或者嵌入式工程师以及C,C++相关的笔试面试必考的题目!接下来我们来看看如何手动实现这些相关的函数. 废话不多说, ...

  5. 第三章 JQuery: HelloWorld--常见方法--css--选择器--筛选器--属性--效果--事件--数组操作--字符串操作--对象转换

    1.jQuery简介 为了简化JavaScript 的开发, 一些JavsScript 库诞生了. JavaScript库封装了很多预定义的对象和实用函数.能帮助使用者建立有高难度交互的页面, 并且兼 ...

  6. C的字符串操作接口实现

    近期在写一个关于用HTTP控制storm的的UI功能.已经实现完毕,採用在nginx里面增加相应的模块调用来实现,模块中调用一个动态载入的SO.这个SO用THRIFT和zookeeper client ...

  7. 一句python,一句R︱python中的字符串操作、中文乱码、NaN情况

    一句python,一句R︱python中的字符串操作.中文乱码.NaN情况 先学了R,最近刚刚上手Python,所以想着将python和R结合起来互相对比来更好理解python.最好就是一句pytho ...

  8. jQuery 工具类函数-字符串操作函数

    调用名为$.trim的工具函数,能删除字符串中左右两边的空格符,但该函数不能删除字符串中间的空格,调用格式为: $.trim (str); 参数str表示需要删除左右两边空格符的字符串. <bo ...

  9. 《手把手教你》系列技巧篇(五十)-java+ selenium自动化测试-字符串操作-上篇(详解教程)

    1.简介 自动化测试中进行断言的时候,我们可能经常遇到的场景.从一个字符串中找出一组数字或者其中的某些关键字,而不是将这一串字符串作为结果进行断言.这个时候就需要我们对字符串进行操作,宏哥这里介绍两种 ...

随机推荐

  1. POI 读取 excel

    xls 和 xlsx 后缀是因为 world excel 版本不一致,需要区别对待 依赖 <dependency> <groupId>org.apache.poi</gr ...

  2. Spring学习之旅(五)极速创建Spring AOP java工程项目

    编译工具:eclipse. 简单说一下,Spring  AOP是干嘛的? 假设你创建了一群类:类A,类B,类C,类D.... 现在你想为每个类都增加一个新功能,那么该怎么办呢?是不是想到了为每个类增加 ...

  3. iOS---------- MBProgressHUD (1.0.0)的变动

    1.改变菊花的颜色 //    hud.color = [UIColor blackColor];-------------->  hud.bezelView.color =[UIColor b ...

  4. 如何获取view的大小

    很多初学者都会犯一个错误 ,就是在onCreate或者onStart里面去获取view的大小,然而这样获取到的宽高通常都是0,为什么呢?因为view的测量过程和activity的生命周期不是同步的,因 ...

  5. Android Studio 之 注释模板

    我们看有的项目的文档,会发现它的注释写的很好看,很规范. 而如果你的代码注释还是在用简单的 // 或者 /**/  ,那就学习一下在Android Studio中如何进行注释模板的设置 首先看下面代码 ...

  6. Android-textview图文混排(网络图片)

    工作太忙,不做过多的解释了,核心是用到了 SpannableStringBuilder  Glide  和 Rxjava 直接上代码了,就两个类. public class ImageSpanAsyn ...

  7. Flutter Plugin开发流程

    这篇文章主要介绍了Flutter Plugin开发流程,包括如何利用Android Studio开发以及发布等. 本文主要给大家介绍如何开发Flutter Plugin中Android的部分.有关Fl ...

  8. openstack nova工作流程

    工作流程请求:nova boot --image ttylinux --flavor 1 i-01nova-api 接受请求,一个tcp REST请求.nova-api 发送一个创建虚拟机的请求到消息 ...

  9. 高通 NXP NFC(PN547PN548) 移植流程 android6.0

    一.驱动部分 首先向NXP 的 fae要android 6.0 bring up的代码,如:NFC_NCIHALx_AR0F.4.3.0_M_NoSE 结构目录如下: 1. 添加驱动文件 高通平台需使 ...

  10. php函数long2ip与ip2long()

    long2ip - Converts an long integer address into a string in (IPv4) Internet standard dotted format s ...