c#性能:类型比较与字符串比较

时间:2008-11-15 00:15:54

标签: c# .net performance string-comparison

哪个更快?这样:

bool isEqual = (MyObject1 is MyObject2)

或者这个:

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

找出哪一个更快会有所帮助。显然,如果你将.ToUpper()应用于字符串比较的每一边,就像程序员经常做的那样,那就需要重新分配影响性能的内存。但是,如果.ToUpper()不像上面的样本那样,那该怎么办?

8 个答案:

答案 0 :(得分:9)

我在这里有点困惑。

正如其他答案所指出的那样,你要比较苹果和橘子。 ::rimshot::

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

如果你想比较字符串,可以使用==运算符(或其他适当的比较方法,如果你需要像对不区分大小写的比较那样花哨的东西)。

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


仔细阅读之后,我认为你想比较字符串比较的速度和参考比较的速度(System.Object基类型中使用的比较类型)。

如果是这种情况,那么答案是参考比较永远不会比任何其他字符串比较慢。 .NET中的参考比较非常类似于比较C中的指针 - 大约和你能得到的一样快。

但是,如果字符串变量s的值为"I'm a string",您会感觉如何,但以下比较失败:

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

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

答案 1 :(得分:5)

根据“最大化.NET性能”一书 电话

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

的性能完全相同
bool isEqual = ("test" == "test");

电话

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

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

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

答案 2 :(得分:4)

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


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

答案 3 :(得分:1)

你告诉我怎么样? :)

this Coding Horror post获取代码,然后插入代码进行测试以代替他的算法。

答案 4 :(得分:0)

使用“==”运算符比较字符串会比较字符串的内容与字符串对象 reference 。比较对象将调用对象的“等于”方法以确定它们是否相等。 Equals的默认实现是进行引用比较,如果两个对象引用都是相同的物理对象,则返回True。这可能比字符串比较更快,但取决于要比较的对象的类型。

答案 5 :(得分:0)

我认为比较第一个例子中的对象的速度和它一样快,因为它只是检查两个对象是否指向内存中的相同地址。

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

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

答案 6 :(得分:0)

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

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

答案 7 :(得分: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);
        }
    }
}