返回首页

简介
本文介绍了在VB.NET中使用的字符串,将推动应用程序的性能,尤其是当代码包含大量字符串,如字符串连接的相关业务的提示和技巧。这篇文章的原始来源是取自。我建议您阅读有关。NET框架,特别是与优化有关的那些有用的文章,在你走之前对这篇文章。字符串声明
声明一个字符串变量,最好的办法是把它设置后直接申报空字符串。它是一种最常见的错误NET开发人员设置一个字符串quot;"或Nothing。这是错误的,因为""是不是真的NET CLR中的一个空字符串,没办法,抛出一个NullReferenceException如果您引用的字符串在后面的代码。。下面是正确的代码字符串声明:

Dim str As String = "" ' wrong

Dim str2 As String = Nothing ' wrong

Dim str3 As String = vbNullString ' wrong

Dim str4 As String = String.Empty ' correct 
字符串串联
连接字符串通常的方法是使用或放大器;运营商。然而,放大器;比快,因为它是专门为字符串设计的同时,也为数字除了工程。{C}优化字符串连接
类似的为String类是所谓的StringBuilder,坐落在System.Text.StringBuilder。 StringBuilder是专为极端的字符串串联提高。它是一种特殊的方式处理。NET CLR。它易于使用,就像String类的操作。如果你知道多少字符串的长度大约在串联结束,您可以设置StringBuilder的构造函数,给出了一个额外的性能提升在这方面的能力:
Dim str As String = "Hello World" & vbCrLf

Dim sb As New System.Text.StringBuilder(str.Length * 4)

For i As Integer = 0 To 4

     sb.Append(str)

Next

Dim final As String = sb.ToString 'get the result string

的StringBuilder还支持使用AppendFormat方法,这是高度优化且易于使用的格式字符串:
Dim names As New StringCollection

names.Add("Mike")

names.Add("Stacy")

names.Add("Bill")

names.Add("Krystelle")



Dim sb As New System.Text.StringBuilder

For Each name As String In names

     sb.AppendFormat("My name is {0}", name)

Next

Dim final As String = sb.ToString

有没有需要实例在同一程序的多个StringBuilders。通过设置Capacity属性0,删除当前字符串,可以重复使用相同的StringBuilder对象:
Dim sb As New System.Text.StringBuilder

'use sb...

sb.Capacity = 0

回答

评论会员:安迪戴维斯 时间:2012/01/25
,一些错误的信息
大多是常识
评论会员:OzgurOzcitak 时间:2012/01/25
再次从其他网站复制/粘贴?如果你是原作者,为什么你转贴你的文章呢?否则你为什么要复制别人的工作?
我建议你​​仔细阅读有关。NET框架,特别是与优化有关的那些有用的文章,在你走之前本文的。

由于你的文章是一个引用的文章逐字拷贝,我为什么要读你看完引用的一个?

修改日(星期二),2009年12月29日下午03:42
:
评论会员:SAKryukov 时间:2012/01/25
对不起我,阿里:

你的另一篇文章中引用的作者:{A}

我不知道为什么会出现在该网站上没有作者的名字... ...

谢尔盖一个Kryukov
评论会员:SAKryukov 时间:2012/01/25
我不会在意那么多,如果有"了无新意"的文章
什么是不是新的,对一些仍然可以为他人的重要和值得写一篇文章。

但我不能忍受说谎
让我们来看看我们在一开始:

阿里Tarhini写道:这是一个最常见的错误NET开发人员""或设置一个字符串。
这是不对的,因为""是不是真的。NET CLR中的一个空字符串,没办法,抛出一个NullReferenceException后如果你在代码中引用的字符串。
住手!是的,使用""是错误的,但只是因为使用即时常数的不良作风,并能伤害保障性。这个简陋的空字符串常量是一个小的伤害,但样的肮脏的根本是因为我们有string.Empty。但是,他说"不"的确是一个空字符串。NET CLR中"?什么是真正的空呢?这是胡言乱语。事实上,"是完全一样string.Empty空的。为什么呢?我猜是因为NET在一些其他的"技术" - ??不是白痴创建

这是比这更有趣。
尝试以下声明:

字符串="";
字符串b ="";
字符串C = string.Empty;

他们不仅在所有字符串比较(你认为还有什么呢?)相当于,他们都参照相同的身份,一E. object.ReferenceEquals将返回true,任何对这些 - 真的是空的 - 串。
这实际持有任何其他的即时字符串常量,至少在相同的堆栈帧。
因此,这一尝试之前,你写文章,不要骗我了!

现在,什么是没有错的呢?这实际上是一个有争议的问题。有些设计使用之间没有本质上的区别和空字符串,表示"未初始化"使用的任何数据一样的东西。当然,这种方法需要的先决条件和后置条件一致的设计有关的方法,所以一些方法,将检查空值的数据,或一些方法将需要,以保证非空。这是所有的设计问题,并没有作者应该假装有一个普遍的规则。作为最低要求,作者应注意这仅仅是他的意见,不是事实。

接下来的事情是这样的:
阿里Tarhini写道:但是,速度比,因为它是专门为字符串设计的同时,也为数字除了工程

好吧,我想这只是作者的幻想。他至少有实验证明这一点呢?
首先,有两个独立的运营商"和"仅仅是一个基本的神器;没有这样的东西在C#和CLI中因此{​​BR}。从理论上说,有一些开销,因为一个字符串和非字符串的串联允许;在这种情况下,非字符串操作数是转换通过调用它的ToString方法(对不起,我不能检查如果在对案件为字符串基本法,因为我不安装它并不愿意这样做)。即使是这样,我简直不能相信,Basic.NET可以这么愚蠢失败优化string.ToString

最后,它是明示或暗示的StringBuilder"提升"字符串连接。我会更加谨慎。其他一些文章解释说,这取决于串联使用是多么广泛。如果仅仅是对或两个串联,简单的可以更快,因为StringBuilder的实例的创建和垃圾收集的开销。
此外,本文并不能说明什么。这是太基本,但在这样一个基本的条款,应解释的字符串是不可改变的,因此,创建新的字符串。
太多的操作数
结论:不仅是本文琐碎,更糟糕的是,因为这是一种误导,它平凡在于
我的一票是太本文:其真正的价值是负数。

谢尔盖一个Kryukov修改上周日,2009年12月27日,日下午09:29
评论会员:阿里Tarhini 时间:2012/01/25
这是我的错,我没有给定的点,你是拒绝进一步的解释,我张贴在这里只是为了解决您的信息。请注意,这篇文章的水平,对于初学者和不为专业人士打算,如果你认为自己亲。这是非常不专业,并undecent提字的"谎言"。无论如何,我会回答有关字符串声明的一部分,并留下您的研究,你都在质疑其他点。

"真的是从性能和代码生成的角度看没有区别,在性能测试中,他们去来回之间其中之一是VS其他速度更快,只有通过毫秒。在寻找幕后的代码,你真的不"看到任何区别,唯一的区别是在IL,这string.Empty使用操作码"ldsfld"和"使用操作码"ldstr"但是这仅仅是因为string.Empty是静态的,并且两个指令做如果你看一下在生产组装的同样的事情。,它是完全一样的。"

C#代码
私人无效名为test1()
{
字符串TEST1 = string.Empty;

字符串test11 = TEST1;}

私人无效的test2()
{
字符串TEST2 ="";
 0;
字符串test22 = TEST2;}

IL代码
私人hidebysig实例。方法无效
TEST1()CIL管理
{
/ /代码大小为10(是0xA)
maxstack 1
当地人的init([0]字符串TEST1,
[1]字符串test11)
IL_0000:NOP
IL_0001:ldsfld字符串[0] System.String:空的
IL_0006:stloc.0
IL_0007:ldloc.0
 60;IL_0008:stloc.1
IL_0009:RET
} / / Form1的方法::TEST1

私人hidebysig实例。方法无效
  ; TEST2()CIL管理
{
/ /代码大小为10(是0xA)
maxstack 1
当地人的init([0]字符串TEST2,
[1]字符串test22)
IL_0000:NOP
IL_0001:ldstr"
IL_0006:stloc.0
IL_0007:ldloc.0
IL_0008:stloc.1
IL_0009:RET
} / / Form1的方法结束:TEST2


-------------------------------------------------{ BR} 私人hidebysig实例。方法无效
 60; TEST2()CIL管理
{
/ /代码大小为10(是0xA)
maxstack 1
当地人的init([0]字符串TEST2,
[1]字符串test22)
IL_0000:NOP
IL_0001:ldstr"
IL_0006:stloc.0
IL_0007:ldloc.0
IL_0008:stloc.1
IL_0009:RET
} / / Form1的方法结束:TEST2
大会的代码
字符串TEST1 = string.Empty;
0000003a MOV EAX,DWORD PTR DS:[022A102Ch]
0000003f MOV DWORD PTR [EBP - 40H],EAX


字符串test11 = TEST1;00000042 MOV EAX,DWORD PTR [EBP - 40H]
00000045 MOV DWORD PTR [EBP - 44H],EAX
-------------------------------------------------- ------------------------------{ BR} 字符串TEST2 ="";
0000003a MOV EAX,DWORD PTR DS:[022A202Ch]
00000040 MOV DWORD PTR [EBP - 40H],EAX

&# 160;
字符串test22 = TEST2;00000043 MOV EAX,DWORD PTR [EBP - 40H]
00000046 MOV DWORD PTR [EBP - 44H],EAX

{A2}
String.Empty和"
正如大卫所暗示的,有String.Empty和"区别??非常小,但是是有区别的。 "??实际上创建了一个对象,它可能会被拉出的字符串实习生池,但仍??而String.Empty创建没有对象??因此,如果你真的最终在记忆效率,我建议String.Empty。然而,你应该记住的区别是如此繁琐,你一定会喜欢永远看不到它在你的代码吗??

{A3}

阿里Tarhini {A4}修订于2009年12月28日(星期一)2:35 AM
评论会员:SAKryukov 时间:2012/01/25
阿里,

非常感谢您在此拆装研究钻研。
您对您的样品拆卸不反驳我的观点,因为你的样品是什么,我建议看不同。
你看,很明显,如果两行是不同的,他们可能会在IL略有不同。
它并不能证明转让的结果是不同的。这里是我的观点。
比较:
第1行:
IL_0001:ldsfld字符串[0] System.String:空的
第2行:
IL_0001:ldstr"
(顺便说一下,请告诉我是C#/ NET版本此处使用 - 以防万一...){ BR}
这两种不同的分配结果如何可以是相同的吗?
首先,我知道一个事实,他们是通过调用object.ReferenceEquals相同。
如果返回true"=="比较,它并不意味着问题的对象是相同的,但它与ReferenceEquals肯定。我可以解释它是如何发生的。字符串成员String.Empty是不是一个常数,它是一个静态只读字段。这意味着它被分配到立即数",排在首位",每到任何立即数的分配产生一个singleton对象的引用,我们可以看到从同一ReferenceEquals检查。好吧,我希望你能证明我错了。

好吧,我也取得了一些积分,你没有答复。无论如何,我建议你更好地利用我的笔记,以修正你的文章。

现在,我觉得你责怪我的"谎言"这个词,对职业道德的理由。好了,因为我从来没有在任何知识领域的专业人士,我用自己的道德标准,但是这不是一个借口。我真的很抱歉,如果我发生了伤害你的感觉和现在的自己为不雅。 你是对的。我只能说这是我情感的方式来吸引注意另一个伦理问题:在发表文章的未经证实的,非验证或以其他方式误导索赔。通过发布,我们应该承担一些道义上的责任。当我看到这种失败,我已经离开一些消极的反应中的一种或另一种方式 - 只是为了帮助你的读者,以避免错误或值得商榷的意见。对我来说,礼貌后的真相 - 对不起

我也有拒绝你参考初学者的观众。这是一个共同的和非常大的错误。你不觉得初学者的需要更准确的信息比经验丰富的吗?有经验的可以理清黄金颗粒从一些细微的污垢时可以很容易误导初学者。

新年快乐!

谢尔盖一个Kryukov
评论会员:onclethomas 时间:2012/01/25
不值得的一篇文章