hac*_*sid 30 .net c# string performance
一位顾问昨天来了,不知怎的,字符串的主题出现了.他提到他已经注意到,对于长度小于一定长度的字符串,Contains
实际上比它更快StartsWith
.我必须用自己的两只眼睛看到它,所以我写了一个小应用程序,当然,Contains
更快!
这怎么可能?
DateTime start = DateTime.MinValue;
DateTime end = DateTime.MinValue;
string str = "Hello there";
start = DateTime.Now;
for (int i = 0; i < 10000000; i++)
{
str.Contains("H");
}
end = DateTime.Now;
Console.WriteLine("{0}ms using Contains", end.Subtract(start).Milliseconds);
start = DateTime.Now;
for (int i = 0; i < 10000000; i++)
{
str.StartsWith("H");
}
end = DateTime.Now;
Console.WriteLine("{0}ms using StartsWith", end.Subtract(start).Milliseconds);
Run Code Online (Sandbox Code Playgroud)
输出:
726ms using Contains
865ms using StartsWith
Run Code Online (Sandbox Code Playgroud)
我也尝试过更长的琴弦!
Kel*_*sey 26
尝试使用StopWatch
测量速度而不是DateTime
检查.
秒表与使用System.DateTime.Now进行计时事件
我认为关键是以下重要部分加粗:
Contains
:
此方法执行序数 (区分大小写和 文化不敏感)比较.
StartsWith
:
此方法使用当前文化执行单词 (区分大小写和文化敏感)比较.
我认为关键是顺序比较,相当于:
序数排序根据字符串中每个Char对象的数值比较字符串.序数比较自动区分大小写,因为字符的小写和大写版本具有不同的代码点.但是,如果案例在您的应用程序中不重要,您可以指定忽略大小写的序数比较.这相当于使用不变文化将字符串转换为大写,然后对结果执行序数比较.
参考文献:
http://msdn.microsoft.com/en-us/library/system.string.aspx
http://msdn.microsoft.com/en-us/library/dy85x1sa.aspx
http://msdn.microsoft.com/en-us/library/baketfxw.aspx
使用Reflector,您可以看到两者的代码:
public bool Contains(string value)
{
return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
}
public bool StartsWith(string value, bool ignoreCase, CultureInfo culture)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (this == value)
{
return true;
}
CultureInfo info = (culture == null) ? CultureInfo.CurrentCulture : culture;
return info.CompareInfo.IsPrefix(this, value,
ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None);
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*hen 24
我想到了.这是因为StartsWith
文化敏感,而Contains不是.这固有意味着StartsWith
必须做更多的工作.
FWIW,这是我在Mono上的结果,其中包含以下(更正)基准:
1988.7906ms using Contains
10174.1019ms using StartsWith
Run Code Online (Sandbox Code Playgroud)
我很高兴看到人们对MS的结果,但我的主要观点是正确完成(并假设类似的优化),我认为StartsWith
必须更慢:
using System;
using System.Diagnostics;
public class ContainsStartsWith
{
public static void Main()
{
string str = "Hello there";
Stopwatch s = new Stopwatch();
s.Start();
for (int i = 0; i < 10000000; i++)
{
str.Contains("H");
}
s.Stop();
Console.WriteLine("{0}ms using Contains", s.Elapsed.TotalMilliseconds);
s.Reset();
s.Start();
for (int i = 0; i < 10000000; i++)
{
str.StartsWith("H");
}
s.Stop();
Console.WriteLine("{0}ms using StartsWith", s.Elapsed.TotalMilliseconds);
}
}
Run Code Online (Sandbox Code Playgroud)
StartsWith
和Contains
表现完全不同,当涉及到文化敏感问题.
特别是,StartsWith
返回true
并不意味着Contains
返回true
.只有当你真正知道自己在做什么时,才应该用另一个替换其中一个.
using System;
class Program
{
static void Main()
{
var x = "A";
var y = "A\u0640";
Console.WriteLine(x.StartsWith(y)); // True
Console.WriteLine(x.Contains(y)); // False
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
19540 次 |
最近记录: |