bool isEqual = (MyObject1 is MyObject2)
或者这样:
bool isEqual = ("blah" == "blah1")
确定哪个更快会很有帮助。显然,如果像程序员经常做的那样将.ToUpper()应用于字符串比较的每一侧,那将需要重新分配内存,这会影响性能。但是,如果像上面的示例中一样不考虑.ToUpper()呢?
bool isEqual = (MyObject1 is MyObject2)
bool isEqual = ("blah" == "blah1")
确定哪个更快会很有帮助。显然,如果像程序员经常做的那样将.ToUpper()应用于字符串比较的每一侧,那将需要重新分配内存,这会影响性能。但是,如果像上面的示例中一样不考虑.ToUpper()呢?
我有点困惑。
正如其他答案所指出的那样,你在比较不同类型的变量。如果你想判断一个对象是否属于某个特定类型,请使用is
运算符。 如果你想比较字符串,请使用 ==
运算符(或其他适当的比较方法,例如大小写不敏感比较等)。 单个操作的速度相对于另一个操作的速度(开玩笑的)似乎并不重要。
经过仔细阅读,我认为您想比较字符串比较的速度与引用比较(System.Object基类型中使用的比较类型)的速度。
如果是这种情况,那么答案是引用比较永远不会比任何其他字符串比较慢。在.NET中进行引用比较就像在C语言中比较指针一样快。
然而,如果一个字符串变量s
的值为"I'm a string"
,但以下比较失败,您会有什么感觉:
if (((object) s) == ((object) "I'm a string")) { ... }
如果你只是比较引用,那取决于s
的值是如何创建的,这种情况可能会发生。如果它最终未被内部化,它将不具有与字面字符串相同的引用,因此比较将失败。因此,您可能会得到一个更快的比较,但并不总是有效。这似乎是一种糟糕的优化。
bool isEqual = String.Equals("test", "test");
与...在性能上完全相同
bool isEqual = ("test" == "test");
bool isEqual = "test".Equals("test");
在理论上,使用非静态的String.Equals方法比调用静态的String.Equals方法慢,但我认为您需要比较数百万个字符串才能真正检测到速度差异。
我的建议是:不要担心哪种字符串比较方法更慢或更快。在正常应用程序中,您永远不会注意到这种差异。您应该使用最容易阅读的方式。
string toto = "toto";
string tata = "tata";
bool isEqual = string.Compare(toto, tata, StringComparison.InvariantCultureIgnoreCase) == 0;
Console.WriteLine(isEqual);
如果我理解问题并且你真的想比较引用相等性和普通的“比较内容”:构建一个测试用例并调用object.ReferenceEquals与a == b进行比较。
注意:你必须理解差异,并且在大多数情况下可能无法使用引用比较。如果你确定这就是你想要的,它可能会快一点。你必须自己尝试并评估是否值得麻烦。
使用“==”运算符比较字符串会比较字符串的内容和字符串对象引用。比较对象将调用对象的“Equals”方法来确定它们是否相等。Equals的默认实现是进行引用比较,如果两个对象引用是相同的物理对象,则返回True。这可能比字符串比较更快,但取决于所比较的对象类型。
我认为,在您的第一个示例中比较对象将是最快的,因为它只是检查两个对象是否指向内存中的同一地址。
正如已经多次提到的那样,也可以比较字符串的地址,但如果这两个字符串来自不同的源,则不一定有效。
最后,通常最好根据类型尝试比较对象。这通常是最具体的识别方法。如果您的对象需要用其他属性表示,而不是它们在内存中的地址,则可以使用其他属性作为标识符。
我觉得这些答案都没有真正回答问题。假设在这个例子中,字符串是类型的名称,我们想知道比较类型名称和类型本身哪个更快。
我进行了测试,令人惊讶的是,在我运行的每个测试中,检查类型名称字符串比检查类型本身要快约10%。我故意使用最简单的字符串和类来测试是否可能更快,结果证明确实可以。不确定对于更复杂的字符串和从大量继承类中比较类型会怎样。当然,这只是微操作,随着语言演变,可能会发生变化。
在我的情况下,我考虑了一个基于此名称切换的值转换器,但它也可以根据类型进行切换,因为每种类型都指定了唯一的类型名称。该值转换器将根据呈现的项目类型确定要显示的字体awesome图标。
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);
}
}
}
checkTypeName()
之前尝试运行checkType()
,并确认性能差异是否仍然存在? - Theodor Zoulias