激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C# - c#基礎(chǔ)系列之System.String的深入理解

c#基礎(chǔ)系列之System.String的深入理解

2022-03-01 13:34大菜 C#

這篇文章主要給大家介紹了關(guān)于c#基礎(chǔ)系列之System.String的深入理解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

幾乎任何一個項(xiàng)目都離不開對字符串的處理,在c和c++編程中,許多程序的漏洞都是由于字符串緩沖區(qū)溢出造成的。為了避免在c#中出現(xiàn)類似的問題,同時也為了使用更方便,c#中專門設(shè)置了兩個字符串處理類:string類和stringbuilder類。

本文主要給大家介紹了關(guān)于c#基礎(chǔ)系列之string的相關(guān)內(nèi)容,分享出來供大家參考學(xué)習(xí),下面話不多說了,來一起看看詳細(xì)的介紹吧

擴(kuò)展閱讀:深入理解值類型和引用類型

基本概念

string(嚴(yán)格來說應(yīng)該是system.string) 類型是我們?nèi)粘oding中用的最多的類型之一。那什么是string呢?^ ~ ^

string是一個不可變的連續(xù)16位的unicode代碼值的集合,它直接派生自system.object類型。

與之對應(yīng)的還有一個不常用的安全字符串類型system.security.securestring,它會在非托管的內(nèi)存上分配,以便避開gc的黑手。主要用于安全性特高的場景。[具體可查看msdn這里不展開討論了。=>msdn查看詳情

特性

  • 由于string類型直接派生于object,所以它是引用類型,那就意味著string對象的實(shí)例總是存在于堆上。
  • string具有不變性,也就是說一旦初始化,它的值將永遠(yuǎn)不變。
  • string類型是封閉的,換言之,你的任何類型不能繼承string。
  • 定義字符串實(shí)例的關(guān)鍵字string只是system.string 類型的一個映射。

c#基礎(chǔ)系列之System.String的深入理解

注意事項(xiàng)

  • 關(guān)于字符串中的回車符和換行符一般大家喜歡直接硬編碼‘\r\n',但是不建議這么做,一旦程序遷移到其他平臺,將出現(xiàn)錯誤。相反,推薦使用system.environment類的newline屬性來生成回車符和換行符,可以跨平臺使用的。
  • 常量字符串的拼接和非常量字符串在clr中行為是不一樣的。具體請查看性能部分。
  • 字符串之前加@符號會改變編譯器的行為,如果加了@符號,編譯器會把string中的轉(zhuǎn)義字符視為正常字符來顯示。也就是我定義的什么內(nèi)容就是什么內(nèi)容,主要在使用文件路徑或者目錄字符串中使用。以下兩個string內(nèi)容的輸出將完全一致。
?
1
2
3
4
5
6
7
8
static void main(string[] args)
 {
  string a = "c:\\temp\\1";
  string b = @"c:\temp\1";
  console.writeline(a);
  console.writeline(b);
  console.read();  
 }

性能

  • c#的編譯器直接支持string類型,并將定義的常量字符串在編譯期直接存放到模塊的元數(shù)據(jù)中。然后會在運(yùn)行時直接加載。這也說明string類型的常量在運(yùn)行時是有特殊待遇的。
  • 由于字符串的不變性,也就意味著多個線程同時操作該字符串不會有任何線程安全的問題。這在某些共享配置的設(shè)計中很有用。
  • 如果程序經(jīng)常會對比重復(fù)度比較高的字符串,這會造成性能上的影響,因?yàn)閷Ρ茸址且?jīng)過幾個步驟的。為此clr引入了一個字符串重用的技術(shù),學(xué)名叫做‘字符串留用'。原理就是:clr會在初始化的時候創(chuàng)建一個內(nèi)部的哈希表,key是字符串,value就是留用字符串在托管堆上的引用。
    string類型提供了兩個靜態(tài)方法來操作這個哈希表:

string.intern

string.isinterned

具體請查看msdn(https://msdn.microsoft.com/zh-cn/library/system.string.isinterned(v=vs.110).aspx)

但是c#編譯器默認(rèn)是不開啟字符串留用功能的,因?yàn)槿绻绦虼罅堪炎址粲茫瑧?yīng)用程序總體性能可能會變得更慢。(微軟也是挺糾結(jié)的,程序員tmd的更糾結(jié))

如果我們的程序中有很多個一模一樣值的常量字符串, c#的編譯器會在編譯期間把這些字符串合并為一個并寫入模塊的元數(shù)據(jù)中,然后修改所有引用該字符串的代碼。這也是一種字符串重用技術(shù),學(xué)名‘字符串池'。這意味著什么呢?這意味著所有值相同的常量字符串其實(shí)引用的是同一個內(nèi)存地址的實(shí)例,在相同值非常多的情況下能顯著提高性能和節(jié)省大量內(nèi)存。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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);
 
 }
}

輸出結(jié)果:

字符串地址= 0x80002d84
字符串地址= 0x80002d84

可見實(shí)例的值只分配了一次,但是有一點(diǎn)需要說明,字符串僅用于編譯期能確定值的字符串,也就是常量字符串。如果我的程序修改為:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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);
 
 }
}

運(yùn)行結(jié)果:

字符串地址= 0x2e3c
字符串地址= 0x2e7c

平時coding避免不了字符串的連接,如果一個頻繁拼接字符串的場景下使用‘+',對程序整體性能和gc影響還是挺大的,為此c#推出了 stringbuilder類型來優(yōu)化字符串的拼接。相對于string類型的不變性來說,stringbuilder更像是可變的字符串類型。它的底層數(shù)據(jù)結(jié)構(gòu)是一個char的數(shù)組。另外還有容量(默認(rèn)為16),最大容量(默認(rèn)為int.maxvalue)等屬性。stringbuilder的優(yōu)勢在于字符總數(shù)未超過‘容量'的時候,底層數(shù)組不會重新分配,這和string每次都重新分配形成最大的對比。如果字符總數(shù)超過‘容量',stringbuilder會自動倍增容量屬性,用一個新的數(shù)組來容納原來的值,原來數(shù)組將會被gc回收。可見如果stringbuilder頻繁的動態(tài)擴(kuò)容也會損害性能,但是影響可能會比string小的多。 合理的設(shè)置stringbuilder初始容量對程序有很大幫助。測試如下:

?
1
2
3
4
5
6
7
8
9
10
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);

運(yùn)行結(jié)果:

14221

查看gc的情況

c#基礎(chǔ)系列之System.String的深入理解

gc執(zhí)行的是如此頻繁。 性能是可想而知的。接著看一下stringbuilder

?
1
2
3
4
5
6
7
8
9
10
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);

運(yùn)行結(jié)果:

12

gc情況:

c#基礎(chǔ)系列之System.String的深入理解

幾乎沒有g(shù)c(可能還未達(dá)到觸發(fā)gc的臨界點(diǎn)),如果我合理初始化了stringbuilder 容量,生產(chǎn)環(huán)境中結(jié)果差距將會更大。 呵呵 ^ ~ ^

其他

關(guān)于字符串留用和字符串池

一個程序集加載的時候,clr默認(rèn)會留用該程序集元數(shù)據(jù)中描述的所有文本常量字符串。由于可能會出現(xiàn)額外的哈希表查找造成的性能下降的現(xiàn)象,所以現(xiàn)在可以禁用這個特性了。

coding中我們平常比較兩個字符串是否相等,那這個過程是怎么樣的呢?

  • 首先判斷字符的數(shù)量是否相等。
  • clr逐個對比字符最終確定是否相等。

這個場景是適合字符串留用的。因?yàn)椴辉傩枰?jīng)過以上的兩個步驟,直接哈希表拿到value就可以對比確定了。

關(guān)于字符串拼接性能

基于以上所有知識,那是不是stringbuilder拼接字符串性能永遠(yuǎn)都高于符號‘+'呢?答案是否定的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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();
 }

運(yùn)行結(jié)果:

+用時: 553
stringbuilder.append 用時: 975

符號‘+'最終會調(diào)用string.concat方法,當(dāng)同時連接幾個字符串時,并不是每連接一個都分配一次內(nèi)存,而是把幾個字符都作為 string.concat方法的參數(shù),只分配一次內(nèi)存。所以在拼接的字符串個數(shù)比較少的場景下,string.concat 性能是略高于stringbuilder.append。string.format 方法最終調(diào)用的是stringbuilder,這里不做展開討論了,請自行參考其他文檔。

所以萬事都不是絕對的!!每個事物都有適合自己的場景,我們都需要自己去探索。(程序員太累了)

以上都是非生產(chǎn)環(huán)境測試結(jié)果,如果錯誤,請及時指正

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。

原文鏈接:https://www.cnblogs.com/zhanlang/p/9612521.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人福利视频在线观看 | 91精品国啪老师啪 | 一级做a爰性色毛片免费 | 日韩做爰视频免费 | 黄色网址在线免费播放 | 日本大片在线播放 | 国内一区| 欧美一级黄色免费 | 日本高清电影在线播放 | a一级黄色大片 | 国产成人在线观看免费 | 国产成人精品一区二区视频免费 | 国产亚洲精品综合一区91555 | 欧美日韩大片在线观看 | 92看片淫黄大片一级 | 免费激情网址 | 精品亚洲在线 | 日韩视频一区二区在线观看 | 国产精品久久久久久久久久久久久久久 | 夜添久久精品亚洲国产精品 | 久久免费视频一区 | 精品国产一区二区亚洲人成毛片 | 青青草好吊色 | 欧美激情精品久久久久久黑人 | 九九热视频这里只有精品 | 免费视频一区 | 黄色视屏免费在线观看 | 亚洲成人高清在线观看 | aaaaaaa毛片| 在线成人精品视频 | 精品久久久久久久久久久aⅴ | www.com国产精品 | 欧美精品免费一区二区三区 | 黄网站在线观 | 成人免费毛片在线观看 | 亚洲xxx在线观看 | 天天操天天干天天操 | 国内自拍网址 | 中文字幕网在线 | 久久久久久久免费看 | 黄色毛片a级 |