span之高性能字符串操作实测
程序员文章站
2022-03-13 13:35:40
.net中的字符串操作性能问题由来已久,幸运的是微软推出了span高性能指针操作封装工具类。这个类到底有多高的性能呢?网上传言反正很高,但是实际上在网上很难找到合适的测试实例,这让本人实在无力吐槽。经不住高性能这三个字的诱惑,本人还是了解了一番后做了几个简单样例来测试一番,下面列出几种字符串常 ......
.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方法可能真的只能在某些地方才能用,不然性能反而会有所下降。
如果对上述感兴趣,可以点击这里下载测试源码,更多请点击左下角的推荐,谢谢~