哪个是快速比较:Convert.ToInt32(stringValue)== intValue或stringValue == intValue.ToString()

Rag*_*hav 12 c# comparison

在开发我的应用程序时,我遇到了一些比较的东西,它是:

    string str = "12345";
    int j = 12345;
    if (str == j.ToString())
    {
        //do my logic
    }
Run Code Online (Sandbox Code Playgroud)

我以为上面的东西也可以用:

    string str = "12345";
    int j = 12345;
    if (Convert.ToInt32(str) == j)
    {
        //do my logic
    }
Run Code Online (Sandbox Code Playgroud)

所以我开发了一个示例代码来测试性能,哪个更好

        var iterationCount = 1000000;
        var watch = new Stopwatch();
        watch.Start();
        string str = "12345";
        int j = 12345;
        for (var i = 0; i < iterationCount; i++)
        {
            if (str == j.ToString())
            {
                //do my logic
            }
        }
        watch.Stop();
Run Code Online (Sandbox Code Playgroud)

第二个:

  var iterationCount = 1000000;
    var watch = new Stopwatch();
    watch.Start();
    string str = "12345";
    int j = 12345;
    for (var i = 0; i < iterationCount; i++)
    {
        if (Convert.ToInt32(str) == j)
        {
            //do my logic
        }
    }
    watch.Stop();
Run Code Online (Sandbox Code Playgroud)

在进行上述两项测试时,我发现上述测试的时间几乎相同.我想讨论哪一个更好的方法?还有其他方法比两个以上的方法更好吗?

Ski*_*izz 16

你的测试存在根本缺陷.编译器和运行时非常聪明,并且会在编译时和运行时优化代码(JIT-ing).在这种情况下,您每次都会执行相同的操作,这将由编译器发现并进行优化,因此每种方法的时序都相似.

试试这个版本(我只有.Net 2.0,因此略有变化):

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace ToStringTest
{
    class Program
    {
        const int
            iterationCount = 1000000;

        static TimeSpan Test1()
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            string str = "12345";
            int j = 12345;
            for (int i = 0; i < iterationCount; i++)
            {
                if (str == i.ToString())
                {
                    //do my logic
                }
            }
            watch.Stop();
            return watch.Elapsed;
        }

        static TimeSpan Test2()
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            string str = "12345";
            int j = 12345;
            for (int i = 0; i < iterationCount; i++)
            {
                if (Convert.ToInt32(i) == j)
                {
                    //do my logic
                }
            }
            watch.Stop();
            return watch.Elapsed;
        }

        static void Main(string[] args)
        {
            Console.WriteLine("ToString = " + Test1().TotalMilliseconds);
            Console.WriteLine("Convert = " + Test2().TotalMilliseconds);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你将看到巨大的差异.一个比另一个快两个数量级.而且它确实是显而易见的.

您需要知道各种操作正在做什么才能知道哪些操作从根本上更快.

将字符串转换为int需要以下内容:

total = 0
for each character in string
  total = total * 10 + value of charater
Run Code Online (Sandbox Code Playgroud)

和ToString需要:

string = ""
while value != 0
  string.AddToFront value % 10
  value /= 10
Run Code Online (Sandbox Code Playgroud)

对于CPU而言,乘法比分区更容易,更快.考虑到选择具有大量乘法的算法而不是具有大量除法的算法,总是选择前者,因为它总是更快.

然后是比较,int-int比较很简单,将每个值加载到寄存器中并进行比较 - 几个机器指令就完成了.两个字符串之间的比较需要一次一个地测试字符串中的每个字符 - 在您给出的示例中,它是5个字节(int可能是4个字节),这是更多的内存访问.


Mat*_*ias 13

好 - 性能不应该是唯一重要的事情.

您应该询问是要比较实际值还是仅比较数字的表示.

采用以下示例:"00001"是否等于1?如果您希望它使用Int.TryParse组合将字符串转换为int,然后比较它们.

根据本地设置,可能还有其他差异.也许用户已设置格式化"1,000,000"之类的数字 - 如果您将该字符串与1000000.ToString()进行比较,结果将为false.


Meh*_*ari 6

我更喜欢,i.ToString() == str因为没有任何保证Convert.ToInt32(str)不会失败.

  • 如果"000123"!= 123,这肯定更好. (3认同)