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

时间:2009-12-16 20:26:05

标签: c# comparison

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

    string str = "12345";
    int j = 12345;
    if (str == j.ToString())
    {
        //do my logic
    }

我在想以上的事情也可以用:

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

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

        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();

第二个:

  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();

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

8 个答案:

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

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

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

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

total = 0
for each character in string
  total = total * 10 + value of charater

并且ToString需要:

string = ""
while value != 0
  string.AddToFront value % 10
  value /= 10

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

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

答案 1 :(得分:13)

嗯 - 表现不应该是唯一重要的事情。

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

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

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

答案 2 :(得分:6)

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

答案 3 :(得分:3)

Yikes,您将域逻辑显示为在分析循环中,因此您没有测试代码的ConvertToString版本之间的时差;您正在测试转换的合并时间以及业务逻辑的执行情况。如果您的业务逻辑很慢并占据转换时间,那么您当然会在每个版本中看到相同的时间。

现在,尽管如此,在您知道这是一个性能瓶颈之前,即使担心这一点,也需要过早优化。特别是,如果执行域逻辑控制转换时间,则两者之间的差异永远不会重要。所以,选择最具可读性的那个。

现在,关于使用哪个版本:您需要首先准确指定您正在测试的内容。你有什么投入? “007”是否会成为输入? “007”与整数7不同吗? “1,024”是否会成为输入?是否存在本地化问题?

答案 4 :(得分:2)

如果性能几乎相同,请使用更具可读性的版本。

就个人而言,我发现.ToString()方法更容易理解,而且更不容易出现另一种方法可能出现的问题。

答案 5 :(得分:2)

语义有点不同。 "01" == 1.ToString() false 1 == Convert.ToInt32("01") true

如果解析可能出错(字符串不是有效数字),那么Int32.TryParse比使用Convert.ToInt32()更快。

答案 6 :(得分:0)

对于初学者来说,将int转换为字符串的第一个如果与int进行比较的字符串不能转换为int,则不会抛出错误。

如果您在批量转换为字符串时进行了大量测试,则会因转换错误而消除可能导致异常抛出的问题。提高异常需要时间并且会减慢第二次测试的速度。

答案 7 :(得分:0)

好的,我进一步提前一步并以这种方式进行测试:

    int j = 123;
    for (var i = 0; i < iterationCount; i++)
    {
        j.ToString();
    }

第二个:             string str =“123”;

        for (var i = 0; i < iterationCount; i++)
        {
            Convert.ToInt32(str);
        }

在这种情况下,我发现每次第二次表现都好一点。在我的情况下,数字仅为100000,而不是100,000。你对这个测试的评论我在这篇文章中做了什么?