比较整数和整数或字符串和字符串是否更有效

时间:2009-10-29 10:05:03

标签: c# performance

我有一个用c#编写的程序,其中有一些int和字符串之间的比较。

因此,出于性能原因,我想知道哪个更有效?

如果我们有:

int a  = 5;
string b = "5";

if(a == int.Parse(b)) { }

OR

if(a.ToString() == b) { }

11 个答案:

答案 0 :(得分:8)

我实际上是使用一些示例和定时循环来描述它。事实证明,小整数的Parse胜利,而大型的ToString胜利。这种差异是如此之小,不应该引起关注,正如其他人所提到的那样,通过考虑字符串根本不代表整数的情况,你可能会做出更好的选择。

编辑:对于有兴趣的人,这里有来源,快速'n'脏:

using System;
using System.Diagnostics;

namespace CompareTest
{
    static class Program
    {
        static void Main(string[] args)
        {
            int iterations = 10000000;
            int a = 5;
            string b = "5";

            Stopwatch toStringStopwatch = new Stopwatch();
            toStringStopwatch.Start();

            for (int i = 0; i < iterations; i++) {
                bool dummyState = a.ToString() == b;
            }

            toStringStopwatch.Stop();

            Stopwatch parseStopwatch = new Stopwatch();
            parseStopwatch.Start();

            for (int i = 0; i < iterations; i++) {
                bool dummyState = a == int.Parse(b);
            }

            parseStopwatch.Stop();

            Console.WriteLine("ToString(): {0}", toStringStopwatch.Elapsed);
            Console.WriteLine("Parse(): {0}", parseStopwatch.Elapsed);
            Console.ReadLine();
        }
    }
}

答案 1 :(得分:5)

一些评论提到运行一个分析工具来证明哪个具有更好的性能。

这是好的,但检查特定语句性能的最简单方法是将它们放在循环中并使用Stopwatch类。

杰夫阿特伍德在this question中询问如何使这种时机变得更简单。在那个问题和答案中,您还会找到一些很好的代码示例和背景细节。

这是一个非常简单的工作示例:

    System.Diagnostics.Stopwatch sw=new System.Diagnostics.Stopwatch();


    int a  = 5;
    string b = "5";

    sw.Start();

    for (int i=0;i<1000000;i++)
    {
        if(a == int.Parse(b))
        {

        } 
    }

    sw.Stop();

    Console.WriteLine("a == int.Parse(b) milliseconds: " + sw.ElapsedMilliseconds);

    sw.Reset();

    sw.Start();

    for (int i=0;i<1000000;i++)
    {
        if(a.ToString() == b)
        {

        }       
    }       

    sw.Stop();

    Console.WriteLine("a.ToString() == b milliseconds: " + sw.ElapsedMilliseconds);

在我的电脑上输出:

a == int.Parse(b)毫秒:521

a.ToString()== b毫秒:697

所以在这个简单的场景中,int.Parse()稍快一点,但还不够真正担心。

答案 2 :(得分:4)

您的选择介于以下之间 代码清单A

int a = 5;
string b = "5";
//Assuming these two values are input received by the application at runtime
int bInt;
if (int.TryParse(b, NumberStyles.None, CultureInfo.InvariantCulture, out bInt) 
    && a.Equals(bInt))
{

}

代码清单B

int a = 5;
string b = "5"; 
//Assuming these two values are input received by the application at runtime
if (string.Compare(b, a.ToString(), StringComparison.Ordinal) != -1)
{

}

我用秒表测试了这个(在所选答案中给出)并且发现代码清单A要快得多。 但是代码清单B更具可读性!

代码清单A节拍if(a == int.Parse(b))

答案 3 :(得分:3)

在内部,ToString和Parse执行以下操作:

<强>解析

value = 0
for each char in string
  value = value * 10 + valueof(char) // i.e. '0' -> 0, '7' -> 7

<强>的ToString

string=""
while value > 0
  string.insert_at_front value % 10 // so that 0 -> '0' and 6 -> '6'
  value /= 10

// on IA32, the % and / can be done at the same time but requires
// a 64bit source for 32bit values

ToString应该比Parse慢,因为除法通常比乘法慢。但是,上面没有考虑Parse和ToString函数在转换期间可能执行的任何开销(即生成异常,分配内存),这意味着它不是更明确的更优化。

从其他答案看,差异似乎是微不足道的,所以只要使用对你更有意义的东西。

答案 4 :(得分:2)

你已经得到了一些好的回答,但是我要补充几点。

  1. 微基准测试的一个众所周知的风险是,少量重复可能最终会测量噪音(例如,时间可能会被传入的电子邮件或IM歪斜),但是大量的重复最终可以测量垃圾收集器的性能(例如,如果您的代码不断创建和丢弃字符串)。

  2. 当我发现自己处于代码中的尴尬境地时,有时候会问自己:“在这种情况下我有什么假设或选择?我能做些什么不同的事情?”例如(只是猜测),当你写“......在int的* [sic] *和字符串之间有很多比较”时,这是否意味着你可能重复使用相同的值(例如,比较新的值)以前的价值观)? 如果是这样,你可以将每个字符串转换为int,并缓存转换后的值以供后续重用,而不必在以后再次转换它吗?

答案 5 :(得分:2)

我把我带到这里的案例是检查&#34; 5&#34; = = 5在一个开关盒中因为我总是会收到0到9之间的数字,我发现最快的方法是: (int)b[0] == 53 所以我采取字符串的第一个字符&#34; 5&#34; (b [0])并将其转换为ACSII值,即53,然后进行比较。结果如下: a == int.Parse(b) milliseconds: 194 a.ToString() == b milliseconds: 142 a == (int)(b[0]) milliseconds: 8 即使这是非常不寻常的情况,大规模阵列的差异是显而易见的;

编辑:正如Dirk Horsten所要求的那样。 我错了。我在帖子中提到我在开关盒上使用它,所以我会在所有情况下使用ASCII值,所以它看起来像这样: switch((int)b[0]) { case 48: Console.WriteLine("0"); break; case 49: Console.WriteLine("1"); break; case 50: Console.WriteLine("2"); break; case 51: Console.WriteLine("3"); break; case 52: Console.WriteLine("4"); break; case 53: Console.WriteLine("5"); break; case 54: Console.WriteLine("6"); break; case 55: Console.WriteLine("7"); break; case 56: Console.WriteLine("8"); break; case 57: Console.WriteLine("9"); break; } 为了一个良好的秩序,这里是你问我的结果: a == int.Parse(b) milliseconds: 184 a.ToString() == b milliseconds: 135 a + 48 ==(int)b[0] milliseconds: 8 正如你所看到的那样,只添加一个添加就没有那么大的区别。

答案 6 :(得分:1)

第一种方法的数字越大。 一个。如果b不是数字,则在尝试比较之前会失败。 湾字符串一次比较长度和数字。

答案 7 :(得分:1)

我怀疑这两个电话会对你的应用程序产生重大影响,除非你真的在大规模创作。

这两种技术都在创建一个新字符串,但int.ToString()必须执行的任务少于int.Parse().

int.ToString()在CLR(comnumber)内部执行。 int.Parse()使用Number.ParseInt32() - &gt;在BCL source内完成Number.StringToNumber() Number.ParseNumber() - &gt; ParseNumber

NumberToString执行大量检查,所以从空中猜测你会想象int.ToString()更快。正如其他人所提到的,使用StopWatch类进行适当的性能测试将是更好的方法。您将需要使用您期望的数字格式来尝试:十进制,十六进制。

您可以比较CLR用于ToString()here的C ++:查找

  • FCIMPL3(用于ToString()和其他格式)在extern中使用,由int.ToString()调用为Int32ToDecStr调用。
  • var x = 5.ToString("D"); var y = 5.ToString(); 用于“D”格式化程序。

C#

{{1}}

我对FCIMPL3错了,如果我是,请纠正我。

答案 8 :(得分:0)

将字符串解析为Int32需要更高的性能,并且对错误更敏感。您必须首先确保Int32.Parse成功。 您也可以使用“==”的替代方法。使用.Equals(),这更容易阅读和理解。

if(b.Equals(a))
{

}

答案 9 :(得分:0)

另外我读somwhere(MSDN)使用以下比==更快的字符串比较

StringA.ToUpperInvariant() == StringB.ToUpperInvariant()

答案 10 :(得分:0)

有许多方法可以表示与字符串相同的数字...