5

哪个更快?这个:

bool isEqual = (MyObject1 is MyObject2)

或这个:

bool isEqual = ("blah" == "blah1")

找出哪个更快会很有帮助。显然,如果您像程序员经常做的那样将 .ToUpper() 应用于字符串比较的每一侧,则需要重新分配内存,这会影响性能。但是,如果 .ToUpper() 不符合上述示例中的等式呢?

4

8 回答 8

11

我在这里有点困惑。

正如其他答案所指出的,您正在比较苹果和橙子。::rimshot::

如果要确定对象是否属于某种类型,请使用is运算符。

如果您想比较字符串,请使用==运算符(或其他适当的比较方法,如果您需要一些花哨的东西,例如不区分大小写的比较)。

一项操作与另一项操作相比有多快(没有双关语)似乎并不重要。


仔细阅读后,我认为您想将字符串比较的速度与引用比较的速度(System.Object 基类型中使用的比较类型)进行比较。

如果是这样,那么答案是引用比较永远不会比任何其他字符串比较慢。.NET 中的引用比较与比较 C 中的指针非常相似 - 尽可能快。

但是,如果字符串变量s具有 value "I'm a string",但以下比较失败,您会有什么感觉:

if (((object) s) == ((object) "I'm a string")) { ... }

如果您只是比较引用,则可能会发生这种情况,具体取决于s创建值的方式。如果它最终没有被实习,它不会有与文字字符串相同的引用,所以比较会失败。因此,您可能会有更快的比较,但并不总是有效。这似乎是一个糟糕的优化。

于 2008-11-15T00:50:40.250 回答
5

根据Maximizing .NET Performance一书,调用

bool isEqual = String.Equals("test", "test");

在性能上与

bool isEqual = ("test" == "test");

通话

bool isEqual = "test".Equals("test");

理论上比调用静态 String.Equals 方法慢,但我认为您需要比较几百万个字符串才能实际检测到速度差异。

我给你的建议是这样的;不要担心哪种字符串比较方法更慢或更快。在正常的应用程序中,您永远不会注意到差异。你应该使用你认为最易读的方式。

于 2008-11-15T00:38:45.253 回答
4

第一个用于比较类型而不是值。如果要将字符串与不敏感的大小写进行比较,可以使用:

string toto = "toto";
string tata = "tata";

bool isEqual = string.Compare(toto, tata, StringComparison.InvariantCultureIgnoreCase) == 0;    

Console.WriteLine(isEqual);     
于 2008-11-15T00:22:54.490 回答
0

我假设比较第一个示例中的对象将尽可能快,因为它只是检查两个对象是否指向内存中的相同地址。

正如已经多次提到的,也可以比较字符串上的地址,但是如果两个字符串是从不同的来源分配的,这不一定有效。

最后,尽可能尝试根据类型比较对象通常是一种很好的形式。它通常是最具体的识别方法。如果您的对象需要用它们在内存中的地址以外的东西来表示,则可以使用其他属性作为标识符。

于 2009-03-28T01:19:38.503 回答
0

你告诉我怎么样?:)

这个 Coding Horror post获取代码,并插入您的代码以代替他的算法进行测试。

于 2008-11-15T00:20:38.800 回答
0

用“==”操作符比较字符串是比较字符串的内容和字符串对象的引用。比较对象会调用对象的“Equals”方法来判断它们是否相等。Equals 的默认实现是进行引用比较,如果两个对象引用是同一个物理对象,则返回 True。这可能比字符串比较快,但取决于被比较对象的类型。

于 2008-11-15T00:43:11.950 回答
0

如果我理解这个问题并且您真的想将引用相等性与普通的“比较内容”进行比较:构建一个测试用例并调用object.ReferenceEquals与 a == b 进行比较。

注意:您必须了解差异是什么,并且在大多数情况下您可能无法使用参考比较。如果你确定这是你想要的,它可能会快一点。您必须自己尝试并评估这是否值得麻烦。

于 2009-12-28T10:45:11.247 回答
0

我觉得这些答案中的任何一个都不能解决实际问题。假设此示例中的字符串是类型的名称,我们试图查看比较类型名称或类型以确定它是什么是否更快。

我把它放在一起,令我惊讶的是,检查类型名称字符串比我运行的每个测试中的类型快 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);
        }
    }
}
于 2020-12-31T19:10:57.970 回答