zoukankan      html  css  js  c++  java
  • span<T>之高性能字符串操作实测

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

    一、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} 毫秒");

     

    二、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             });

    三、String.Split 测试

    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} 毫秒");

    四、String.Replace 测试

    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中表现还不如原生的。

    一、String.Contains 测试

    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里面有其它的大小写和语言相关的判断啊。好,那再换一个原生方法对比测试一下。

    二、String.Compare 测试

    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方法可能真的只能在某些地方才能用,不然性能反而会有所下降。

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

  • 相关阅读:
    toj 2819 Travel
    toj 2807 Number Sort
    zoj 2818 Prairie dogs IV
    zoj 1276 Optimal Array Multiplication Sequence
    toj 2802 Tom's Game
    toj 2798 Farey Sequence
    toj 2815 Searching Problem
    toj 2806 Replace Words
    toj 2794 Bus
    css截取字符
  • 原文地址:https://www.cnblogs.com/yswenli/p/9987762.html
Copyright © 2011-2022 走看看