亳州人事网,逆隋txt全集下载,柴智屏图片
“大菜”:源于自己刚踏入猿途混沌时起,自我感觉不是一般的菜,因而得名“大菜”,于自身共勉。
扩展阅读:
string(严格来说应该是system.string) 类型是我们日常coding中用的最多的类型之一。那什么是string呢?^ ~ ^
string是一个不可变的连续16位的unicode代码值的集合,它直接派生自system.object类型。
与之对应的还有一个不常用的安全字符串类型system.security.securestring,它会在非托管的内存上分配,以便避开gc的黑手。主要用于安全性特高的场景。[具体可查看msdn这里不展开讨论了。
常量字符串的拼接和非常量字符串在clr中行为是不一样的。具体请查看性能部分。
static void main(string[] args) { string a = "c:\\temp\\1"; string b = @"c:\temp\1"; console.writeline(a); console.writeline(b); console.read(); }
string.intern
string.isinterned
具体请查看msdn(https://msdn.microsoft.com/zh-cn/library/system.string.isinterned(v=vs.110).aspx)
但是c#编译器默认是不开启字符串留用功能的,因为如果程序大量把字符串留用,应用程序总体性能可能会变得更慢。(微软也是挺纠结的,程序员tmd的更纠结)
string s1 = "hello 大菜"; string s2 = "hello 大菜"; unsafe { fixed (char* p = s1) { console.writeline("字符串地址= 0x{0:x}", (int)p); } fixed (char* p = s2) { console.writeline("字符串地址= 0x{0:x}", (int)p); } }
输出结果:
字符串地址= 0x80002d84 字符串地址= 0x80002d84
可见实例的值只分配了一次,但是有一点需要说明,字符串仅用于编译期能确定值的字符串,也就是常量字符串。如果我的程序修改为:
args = new string[] { "dfasfdsa"}; string s1 = "hello 大菜"+ args[0]; string s2 = "hello 大菜"+args[0]; unsafe { fixed (char* p = s1) { console.writeline("字符串地址= 0x{0:x}", (int)p); } fixed (char* p = s2) { console.writeline("字符串地址= 0x{0:x}", (int)p); } }
运行结果:
字符串地址= 0x2e3c 字符串地址= 0x2e7c
int count = 100000; stopwatch sw = new stopwatch(); sw.start(); string s = ""; for (int i = 0; i < count; i++) { s += i.tostring(); } sw.stop(); console.writeline(sw.elapsedmilliseconds);
运行结果:
14221
查看gc的情况
gc执行的是如此频繁。 性能是可想而知的。接着看一下stringbuilder
int count = 100000; stopwatch sw = new stopwatch(); sw.start(); stringbuilder sb = new stringbuilder();//听说程序员都这样命名stringbuilder for (int i = 0; i < count; i++) { sb.append(i.tostring()); } sw.stop(); console.writeline(sw.elapsedmilliseconds);
运行结果:
12
gc情况:
几乎没有gc(可能还未达到触发gc的临界点),如果我合理初始化了stringbuilder 容量,生产环境中结果差距将会更大。 呵呵 ^ ~ ^
这个场景是适合字符串留用的。因为不再需要经过以上的两个步骤,直接哈希表拿到value就可以对比确定了。
基于以上所有知识,那是不是stringbuilder拼接字符串性能永远都高于符号‘+’呢?答案是否定的。
static void main(string[] args) { int count = 10000000; stopwatch sw = new stopwatch(); sw.start(); string str1 = "str1", str2 = "str2", str3 = "str3"; for (int i = 0; i < count; i++) { string s = str1 + str2 + str3; } sw.stop(); console.writeline($@"+用时: {sw.elapsedmilliseconds}" ); sw.reset(); sw.start(); for (int i = 0; i < count; i++) { stringbuilder sb = new stringbuilder();//听说程序员都这样命名stringbuilder sb.append(str1).append(str2).append(str3); } sw.stop(); console.writeline($@"stringbuilder.append 用时: {sw.elapsedmilliseconds}"); console.read(); }
运行结果:
+用时: 553 stringbuilder.append 用时: 975
符号‘+’最终会调用string.concat方法,当同时连接几个字符串时,并不是每连接一个都分配一次内存,而是把几个字符都作为 string.concat方法的参数,只分配一次内存。所以在拼接的字符串个数比较少的场景下,string.concat 性能是略高于stringbuilder.append。string.format 方法最终调用的是stringbuilder,这里不做展开讨论了,请自行参考其他文档。
所以万事都不是绝对的!!每个事物都有适合自己的场景,我们都需要自己去探索。(程序员太累了)
以上都是非生产环境测试结果,如果错误,请及时指正
请尊重一个猿的辛苦,转载请标明出处 ^ ~ ^ 。部分图片来源于网络,如有侵权请及时联系。让我们一起进步吧
一个不止于it圈内容的微信公众号,欢迎关注,交流更多的it知识。不定时会有惊喜奥 ^ ~ ^
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Net Core Web Api项目与在NginX下发布的方法
asp.net core3.1 引用的元包dll版本兼容性问题解决方案
IdentityServer4实现.Net Core API接口权限认证(快速入门)
ASP.NET Core MVC通过IViewLocationExpander扩展视图搜索路径的实现
网友评论