哪个更快?这个:
bool isEqual = (MyObject1 is MyObject2)
或这个:
bool isEqual = ("blah" == "blah1")
找出哪个更快会很有帮助。显然,如果您像程序员经常做的那样将 .ToUpper() 应用于字符串比较的每一侧,则需要重新分配内存,这会影响性能。但是,如果 .ToUpper() 不符合上述示例中的等式呢?
哪个更快?这个:
bool isEqual = (MyObject1 is MyObject2)
或这个:
bool isEqual = ("blah" == "blah1")
找出哪个更快会很有帮助。显然,如果您像程序员经常做的那样将 .ToUpper() 应用于字符串比较的每一侧,则需要重新分配内存,这会影响性能。但是,如果 .ToUpper() 不符合上述示例中的等式呢?
我在这里有点困惑。
正如其他答案所指出的,您正在比较苹果和橙子。::rimshot::
如果要确定对象是否属于某种类型,请使用is
运算符。
如果您想比较字符串,请使用==
运算符(或其他适当的比较方法,如果您需要一些花哨的东西,例如不区分大小写的比较)。
一项操作与另一项操作相比有多快(没有双关语)似乎并不重要。
仔细阅读后,我认为您想将字符串比较的速度与引用比较的速度(System.Object 基类型中使用的比较类型)进行比较。
如果是这样,那么答案是引用比较永远不会比任何其他字符串比较慢。.NET 中的引用比较与比较 C 中的指针非常相似 - 尽可能快。
但是,如果字符串变量s
具有 value "I'm a string"
,但以下比较失败,您会有什么感觉:
if (((object) s) == ((object) "I'm a string")) { ... }
如果您只是比较引用,则可能会发生这种情况,具体取决于s
创建值的方式。如果它最终没有被实习,它不会有与文字字符串相同的引用,所以比较会失败。因此,您可能会有更快的比较,但并不总是有效。这似乎是一个糟糕的优化。
根据Maximizing .NET Performance一书,调用
bool isEqual = String.Equals("test", "test");
在性能上与
bool isEqual = ("test" == "test");
通话
bool isEqual = "test".Equals("test");
理论上比调用静态 String.Equals 方法慢,但我认为您需要比较几百万个字符串才能实际检测到速度差异。
我给你的建议是这样的;不要担心哪种字符串比较方法更慢或更快。在正常的应用程序中,您永远不会注意到差异。你应该使用你认为最易读的方式。
第一个用于比较类型而不是值。如果要将字符串与不敏感的大小写进行比较,可以使用:
string toto = "toto";
string tata = "tata";
bool isEqual = string.Compare(toto, tata, StringComparison.InvariantCultureIgnoreCase) == 0;
Console.WriteLine(isEqual);
我假设比较第一个示例中的对象将尽可能快,因为它只是检查两个对象是否指向内存中的相同地址。
正如已经多次提到的,也可以比较字符串上的地址,但是如果两个字符串是从不同的来源分配的,这不一定有效。
最后,尽可能尝试根据类型比较对象通常是一种很好的形式。它通常是最具体的识别方法。如果您的对象需要用它们在内存中的地址以外的东西来表示,则可以使用其他属性作为标识符。
你告诉我怎么样?:)
从这个 Coding Horror post获取代码,并插入您的代码以代替他的算法进行测试。
用“==”操作符比较字符串是比较字符串的内容和字符串对象的引用。比较对象会调用对象的“Equals”方法来判断它们是否相等。Equals 的默认实现是进行引用比较,如果两个对象引用是同一个物理对象,则返回 True。这可能比字符串比较快,但取决于被比较对象的类型。
如果我理解这个问题并且您真的想将引用相等性与普通的“比较内容”进行比较:构建一个测试用例并调用object.ReferenceEquals与 a == b 进行比较。
注意:您必须了解差异是什么,并且在大多数情况下您可能无法使用参考比较。如果你确定这是你想要的,它可能会快一点。您必须自己尝试并评估这是否值得麻烦。
我觉得这些答案中的任何一个都不能解决实际问题。假设此示例中的字符串是类型的名称,我们试图查看比较类型名称或类型以确定它是什么是否更快。
我把它放在一起,令我惊讶的是,检查类型名称字符串比我运行的每个测试中的类型快 10%。我故意使用最简单的字符串和类来看看是否有可能更快,结果证明这是可能的。不确定来自重度继承类的更复杂的字符串和类型比较。这当然是一个微操作,可能会在我想的语言演变的某个时刻发生变化。
就我而言,我正在考虑一个基于此名称切换的值转换器,但它也可以切换类型,因为每种类型都指定一个唯一的类型名称。值转换器会根据呈现的项目类型计算出要显示的字体真棒图标。
using System;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApp1
{
public sealed class A
{
public const string TypeName = "A";
}
public sealed class B
{
public const string TypeName = "B";
}
public sealed class C
{
public const string TypeName = "C";
}
class Program
{
static void Main(string[] args)
{
var testlist = Enumerable.Repeat(0, 100).SelectMany(x => new object[] { new A(), new B(), new C() }).ToList();
int count = 0;
void checkTypeName()
{
foreach (var item in testlist)
{
switch (item)
{
case A.TypeName:
count++;
break;
case B.TypeName:
count++;
break;
case C.TypeName:
count++;
break;
default:
break;
}
}
}
void checkType()
{
foreach (var item in testlist)
{
switch (item)
{
case A _:
count++;
break;
case B _:
count++;
break;
case C _:
count++;
break;
default:
break;
}
}
}
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 100000; i++)
{
checkTypeName();
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
sw.Restart();
for (int i = 0; i < 100000; i++)
{
checkType();
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
}
}