Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#性能:类型比较与字符串比较_C#_.net_Performance_String Comparison - Fatal编程技术网

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

c#性能:类型比较与字符串比较,c#,.net,performance,string-comparison,C#,.net,Performance,String Comparison,哪个更快?这: bool isEqual = (MyObject1 is MyObject2) 或者这个: bool isEqual = ("blah" == "blah1") 这将有助于找出哪一个更快。显然,如果像程序员经常做的那样将.ToUpper()应用于字符串比较的每一侧,则需要重新分配内存,这会影响性能。但是,如果.ToUpper()不符合上述示例中的等式呢?你能告诉我吗?:) 从中获取代码,并插入要测试的代码来代替他的算法。第一个用于比较类型而不是值。 如果要将字符串与非敏感大小

哪个更快?这:

bool isEqual = (MyObject1 is MyObject2)
或者这个:

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

你能告诉我吗?:)


从中获取代码,并插入要测试的代码来代替他的算法。

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

string toto=“toto”;
字符串tata=“tata”;
bool isEqual=string.Compare(toto、tata、StringComparison.invariantCultureInogoreCase)==0;
控制台写入线(等质量);

根据《最大化.NET性能》一书 电话

在性能上与相同

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

bool isEqual = "test".Equals("test");
理论上比调用static String.Equals方法慢,但我认为您需要比较数百万个字符串,以便实际检测速度差异


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

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

我在这里有点困惑

正如其他答案所指出的,你在比较苹果和桔子<代码>::rimshot::

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

如果要比较字符串,请使用
==
运算符(如果需要不区分大小写的比较,请使用其他适当的比较方法)

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


仔细阅读后,我认为您需要比较字符串比较的速度和引用比较的速度(System.Object base type中使用的比较类型)

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

但是,如果字符串变量
s
的值为
“我是字符串”
,但以下比较失败,您会有什么感觉:

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

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

我假设比较第一个示例中的对象的速度与比较速度差不多,因为它只是检查两个对象是否指向内存中的相同地址

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


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

如果我理解这个问题,并且您真的想将引用相等性与普通的“比较内容”进行比较:构建一个测试用例,并根据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);
        }
    }
}
使用系统;
使用系统诊断;
使用System.Linq;
名称空间控制台EAPP1
{
公众密封A类
{
public const string TypeName=“A”;
}
B级公众密封
{
public const string TypeName=“B”;
}
C类公众密封
{
public const string TypeName=“C”;
}
班级计划
{
静态void Main(字符串[]参数)
{
var testlist=Enumerable.Repeat(01100).SelectMany(x=>newobject[]{newa(),newb(),newc()}).ToList();
整数计数=0;
无效支票
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);
        }
    }
}