Eri*_*ric 10 c# string content-length
我正在努力加快以下方面的步伐:
string s; //--> s is never null
if (s.Length != 0)
{
<do something>
}
Run Code Online (Sandbox Code Playgroud)
问题是,看起来.Length实际上是对字符串中的字符进行计数,这比我需要的工作更多.有人知道如何加快速度吗?
或者,有没有办法确定s [0]是否存在,w/out检查字符串的其余部分?
Jon*_*eet 23
编辑:现在您已经提供了更多上下文:
试图重现这一点,我根本找不到瓶颈string.Length.使其更快的唯一方法是注释掉if块的测试和正文 - 这不是很公平.只是注释掉条件会减慢速度,即无条件地复制引用比检查条件要慢.
正如已经指出的那样,使用其重载string.Split为您移除空条目是真正的杀手优化.
您可以通过避免每次只创建一个空格来创建一个新的char数组.你总是会有效地传递同样的东西,为什么不利用它呢?
空数组实际上是不可变的.您可以通过始终返回相同的内容来优化null/empty案例.
优化的代码变为:
private static readonly char[] Delimiters = " ".ToCharArray();
private static readonly string[] EmptyArray = new string[0];
public static string[] SplitOnMultiSpaces(string text)
{
if (string.IsNullOrEmpty(text))
{
return EmptyArray;
}
return text.Split(Delimiters, StringSplitOptions.RemoveEmptyEntries);
}
Run Code Online (Sandbox Code Playgroud)
String.Length压根就没有指望字符串中的字母.该值存储为一个字段 - 尽管我似乎记得该字段的最高位用于记住所有字符是否都是ASCII(或者过去常常用于启用其他优化).所以属性访问可能需要做一个位掩码,但它仍然是O(1)并且我希望JIT也可以内联它.(它是作为一个实现的extern,但希望在这种情况下不会影响JIT - 我怀疑它是一个足够普遍的操作,可能有特殊的支持.)
如果您已经知道该字符串不为null,那么您现有的测试
if (s.Length != 0)
Run Code Online (Sandbox Code Playgroud)
如果你正在寻找原始性能IMO,那么这是最好的方法.我个人在大多数情况下写道:
if (s != "")
Run Code Online (Sandbox Code Playgroud)
更清楚的是,我们对长度的兴趣并不像是否为空字符串.这将比长度测试略慢,但我相信它更清晰.与以往一样,我会选择最清晰的代码,直到你有基准/分析数据来表明这确实是一个瓶颈.我知道你的问题明确是关于找到最有效的测试,但我想我还是会提到这个.你有证据证明这是一个瓶颈吗?
编辑:只是为了给出我不使用的建议更明确的原因string.IsNullOrEmpty:对该方法的调用向我建议调用者明确地尝试处理变量为null的情况,否则他们就不会提到它.如果在代码的这一点上,如果变量为 null 则将其视为错误,那么您不应该尝试将其作为正常情况处理.
在这种情况下,Length检查实际上比我建议的不等式测试更好:它充当隐式断言,即变量不为空.如果你有一个bug而且它是 null,那么测试将抛出一个异常,并且会及早发现bug.如果使用相等性测试,它会将null视为与空字符串不同,因此它将进入"if"语句的主体.如果你使用string.IsNullOrEmpty它会将null视为与空相同,因此它不会进入块.
String.IsNullOrEmpty是检查null或零长度字符串的首选方法.
在内部,它将使用长度.但是,不应该动态计算字符串的Length属性.
如果您完全确定该字符串永远不会为null并且您对String.IsNullOrEmpty有强烈的反对意见,那么我能想到的最有效的代码是:
if(s.Length > 0)
{
// Do Something
}
Run Code Online (Sandbox Code Playgroud)
或者,甚至可能更好:
if(s != "")
{
// Do Something
}
Run Code Online (Sandbox Code Playgroud)
访问该Length属性不应该进行计数 - .NET字符串在对象内部存储计数.
所述SSCLI /转子的源代码包含一个有趣的评论,这表明String.Length为(a)有效和(b)魔术:
// Gets the length of this string
//
/// This is a EE implemented function so that the JIT can recognise is specially
/// and eliminate checks on character fetchs in a loop like:
/// for(int I = 0; I < str.Length; i++) str[i]
/// The actually code generated for this will be one instruction and will be inlined.
//
public extern int Length {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
}
Run Code Online (Sandbox Code Playgroud)