哪个更快?GUID转换和比较字符串比较有多贵?
bool same=(Guid)Identifier==id;
bool same=String.Equals(string1,string2, StringComparison.OrdinalIgnoreCase);
哪个更快?GUID转换和比较字符串比较有多贵?
bool same=(Guid)Identifier==id;
bool same=String.Equals(string1,string2, StringComparison.OrdinalIgnoreCase);
我用这个代码:
object victim = Guid.Empty;
Guid target = Guid.NewGuid();
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 10000000; i++){
bool equal = ((Guid) victim) == target;
}
Console.WriteLine("Direct cast : {0}", sw.Elapsed);
sw.Reset(); sw.Start();
for (int i = 0; i < 10000000; i++)
{
bool equal = Guid.Equals(victim, target);
}
Console.WriteLine("Guid.Equals : {0}", sw.Elapsed);
sw.Reset(); sw.Start();
string a = victim.ToString(); // as suggested by Mikael
string b = target.ToString();
for (int i = 0; i < 10000000; i++)
{
bool equal = String.Equals(a, b, StringComparison.OrdinalIgnoreCase);
}
Console.WriteLine("String.Equals : {0}", sw.Elapsed);
Console.ReadLine();
,得到了这样的结果对于不同的值(最好的情况):
object victim = Guid.Empty;
Guid target = Guid.NewGuid();
// Direct cast : 00:00:00.1164198
// Guid.Equals : 00:00:02.1268147
// String.Equals : 00:00:00.4129527 // oh my!
而这一结果对于相同的值(糟糕的情况下)
object victim = Guid.Empty;
Guid target = Guid.Empty;
// Direct cast : 00:00:00.2793173
// Guid.Equals : 00:00:03.5625948
// String.Equals : 00:00:01.7564302
这是最好的答案,因为它实际上显示了一个基准... –
您的基准测试在字节1上进行了比较,这是尽力而为的。如果你比较更多的字节时间会有更多的不同。 但是时间差异并不像你声称的那么大,因为你已经在循环中包含了.ToString()。 string a = victim.ToString(); string b = target.ToString(); for(int i = 0; i <10000000; i ++) { bool equal = String.Equals(a,b, StringComparison.OrdinalIgnoreCase); } –
@Mikael,不错的提示;你的建议会导致string.equals性能的巨大改进。 –
一个GUID ==的Guid将使用如下代码:
public bool Equals(Guid g)
{
if (g._a != this._a)
{
return false;
}
if (g._b != this._b)
{
return false;
}
而串在你的例子比较会使用不安全的指针比较。
没有基准测试,我怀疑Guid会更快,但我们说的是边际。而且你真的需要提高数以百万计的比较数量。
两个比较都会提前爆发,意味着从左到右,这样也会影响速度。字符串比较在比较发生之前有更多的检查,还有一个方法调用。
是什么让它更安全? – zsharp
他说速度更快,并不安全,但我很好奇看到不区分大小写的字符串比较如何使用指针比较。 –
“不安全”的关键字不一定是不安全的,但它可以让你像使用C++一样使用内存指针。 .Net框架中的许多功能都是以这种方式实现的。所以,这两种方式都同样可以放心使用:) 我只是指实际的功能在框架 - 私有静态不安全INT CompareOrdinalIgnoreCaseHelper(STRA字符串,字符串STRB) –
GUID比较是一个16字节的memcmp。它不会比字符串比较糟糕,但如果你关心性能,你不应该使用托管代码。
他的字符串比较是不区分大小写的。尽管时间上的比较应该不会有太大的不同,但它并不像Guid那样是逐字节的比较。 –
不是。 .net guid由Int32 + Int16 + Int16 +(字节* 8)组成。它会比较一个到另一个,直到最后一个字节。意思是最多11次比较。 –
托管代码实际上非常快 - 比我上次检查的C++慢25-50%左右,与Java相同......比较Python/Ruby比较慢8,000%,PHP比慢5万... –
在我做一个UUID-UUID比较VS String-String比较的测试中,UUID比较大约需要1/4的时间作为字符串比较。
但是,String-> UUID的投射很昂贵。比UUID->字符串转换贵得多。两者都比任何一种比较方法都贵。
因此: 如果您有两个UUID直接比较UUID。 如果你有两个字符串直接比较字符串。 如果您有一个字符串和一个UUID,请将UUID转换为字符串并比较字符串。
.NET Guid是一个16字节的结构,当以字符串形式表示时,将以此模式格式化“xxxxxxxx-xxxx- xxxx-xxxx-xxxxxxxxxxxx“,大约32个字符。
所以表示为GUID需要16个字节, 表示为一个字符串,需要32 * 2 = 64个字节。
因此GUID.Equals()应该表现更好。
此外,GUID.Equals(GUID)将执行更好,然后guid1 == guid2,因为前者没有涉及拳击。
'Guid.Equals(object,object)'所以你会有un/boxing参与;请在那里看到我的基准 –
Guid.Equals(Guid)在这里描述。 http://msdn.microsoft.com/en-us/library/asw89aw8.aspx。看起来像这个过载没有涉及拳击。 – Santhosh
对不起,我以为你在谈论静态版本;但是,无论如何,你需要使用Guid.Equals(对象)作为整体关于从对象投射 –
是不是很容易测试? –
类似(但不相同)的问题在这里http://stackoverflow.com/questions/713109/performance-using-guid-object-or-guid-string-as-key –
什么时候会这样吗?这听起来像是一种微型优化,应该不惜一切代价避免这种情况。请记住,首先让它工作,而不是(如果需要)使其更快。 –