span之高性能字符串操做实测

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

1、String.Index 测试性能

1             var t1 = StopWacherHelper.DoTimer(() =>
2             {
3                 for (int i = 0; i < count; i++)
4                 {
5                     str.IndexOf(subStr);
6                 }
7             });
8 
9             Console.WriteLine($"string.IndexOf {count} 次用时:{t1} 毫秒");
 1             var t2 = StopWacherHelper.DoTimer(() =>
 2             {
 3                 var strSpan = str.AsSpan();
 4 
 5                 var subStrSpan = subStr.AsSpan();
 6 
 7                 for (int i = 0; i < count; i++)
 8                 {
 9                     strSpan.IndexOf(subStrSpan);
10                 }
11             });
12 
13             Console.WriteLine($"Span<T>.IndexOf {count} 次用时:{t2} 毫秒");

 

2、String.Substring 测试测试

1             var t1 = StopWacherHelper.DoTimer(() =>
2             {
3                 for (int i = 0; i < count; i++)
4                 {
5                     str.Substring(0, str.IndexOf(subStr));
6                 }
7             });
8 
9             Console.WriteLine($"String.Substring {count} 次用时:{t1} 毫秒");
 1             var t2 = StopWacherHelper.DoTimer(() =>
 2             {
 3                 var strSpan = str.AsSpan();
 4 
 5                 var subStrSpan = subStr.AsSpan();
 6 
 7                 var index = strSpan.IndexOf(subStrSpan);
 8 
 9                 for (int i = 0; i < count; i++)
10                 {
11                     strSpan.Slice(0, strSpan.IndexOf(subStrSpan));
12                 }
13             });

3、String.Split 测试spa

1             var t1 = StopWacherHelper.DoTimer(() =>
2             {
3                 for (int i = 0; i < count; i++)
4                 {
5                     var arr = str.Split(new string[] { splitStr }, StringSplitOptions.None);
6                 }
7             });
8 
9             Console.WriteLine($"String.Split {count} 次用时:{t1} 毫秒");
 1             var t2 = StopWacherHelper.DoTimer(() =>
 2             {
 3                 var strSpan = str.AsSpan();
 4 
 5                 var splitSapn = splitStr.AsSpan();
 6 
 7                 int m = 0, n = 0;
 8 
 9                 for (int i = 0; i < count; i++)
10                 {
11                     List<string> arr = new List<string>();
12 
13                     while (true)
14                     {
15                         m = n;
16                         n = strSpan.IndexOf(splitSapn);
17                         if (n > -1)
18                         {
19                             arr.Add(strSpan.Slice(0, n).ToString());
20                             strSpan = strSpan.Slice(n + splitSapn.Length);
21                         }
22                         else
23                         {
24                             break;
25                         }
26                     }
27 
28                 }
29             });
30 
31             Console.WriteLine($"Span<T>.Split {count} 次用时:{t2} 毫秒");

4、String.Replace 测试.net

1             var t1 = StopWacherHelper.DoTimer(() =>
2             {
3                 for (int i = 0; i < count; i++)
4                 {
5                     str.Replace(splitStr, replaceStr);
6                 }
7             });
8 
9             Console.WriteLine($"String.Replace {count} 次用时:{t1} 毫秒");
 1             var t2 = StopWacherHelper.DoTimer(() =>
 2             {
 3                 var strSpan = str.AsSpan();
 4 
 5                 var splitSapn = splitStr.AsSpan();
 6 
 7                 int m = 0, n = 0;
 8 
 9                 for (int i = 0; i < count; i++)
10                 {
11                     List<string> arr = new List<string>();
12 
13                     while (true)
14                     {
15                         m = n;
16                         n = strSpan.IndexOf(splitSapn);
17                         if (n > -1)
18                         {
19                             arr.Add(strSpan.Slice(0, n).ToString());
20                             strSpan = strSpan.Slice(n + splitSapn.Length);
21                         }
22                         else
23                         {
24                             break;
25                         }
26                     }
27                     string.Join(replaceStr, arr);
28                 }
29             });
30 
31             Console.WriteLine($"Span<T>.Replace {count} 次用时:{t2} 毫秒");

 

  怎么样,通过上面的测试,是否是觉的Span<T>确实是名不虚传?的确,在上面几个常见场景中,Span<T>的高性能确实与众不同,差很少是10倍的性能优点!看到这里,小伙伴们是否是觉的字符串操做全改为Span<T>就好了?那下面的两个测试会让你们看清现实,在String.Contains中表现还不如原生的。指针

1、String.Contains 测试code

1             var t1 = StopWacherHelper.DoTimer(() =>
2             {
3                 for (int i = 0; i < count; i++)
4                 {
5                     str.Contains(subStr);
6                 }
7             });
8 
9             Console.WriteLine($"string.Contains {count} 次用时:{t1} 毫秒");
 1             var t2 = StopWacherHelper.DoTimer(() =>
 2             {
 3                 var strSpan = str.AsSpan();
 4 
 5                 var subStrSpan = subStr.AsSpan();
 6 
 7                 for (int i = 0; i < count; i++)
 8                 {
 9                     strSpan.Contains(subStrSpan, StringComparison.CurrentCulture);
10                 }
11             });
12 
13             Console.WriteLine($"Span<T>.Contains {count} 次用时:{t2} 毫秒");

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

2、String.Compare 测试ip

1             var t1 = StopWacherHelper.DoTimer(() =>
2             {
3                 for (int i = 0; i < count; i++)
4                 {
5                     string.Compare(str, subStr, true);
6                 }
7             });
8 
9             Console.WriteLine($"string.Compare {count} 次用时:{t1} 毫秒");
 1             var t2 = StopWacherHelper.DoTimer(() =>
 2             {
 3                 var strSpan = str.AsSpan();
 4 
 5                 var subStrSpan = subStr.AsSpan();
 6 
 7                 for (int i = 0; i < count; i++)
 8                 {
 9                     strSpan.Contains(subStrSpan, StringComparison.CurrentCultureIgnoreCase);
10                 }
11             });
12 
13             Console.WriteLine($"Span<T>.Contains {count} 次用时:{t2} 毫秒");

  仍是被反杀了,这说明Span<T>的这个Contains方法可能真的只能在某些地方才能用,否则性能反而会有所降低。字符串

       若是对上述感兴趣,能够点击这里下载测试源码,更多请点击左下角的推荐,谢谢~

相关文章
相关标签/搜索