-3

I do a lot of comparisons between strings and integers and was wondering which of the two offers better performance.

This one:

int a = 1;
string b = "1";
bool isEqual = a == int.Parse(b);

or this one:

int a = 1;
string b = "1";
bool isEqual = a.ToString() == b;

EDIT: After Elliott Frisch's comment I wrote the code below to benchmark, which I got from this: https://stackoverflow.com/a/15108875/629211. The accepted answer works too.

int a = 1;
string b = "1";

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

for (int i = 1; i < 1000000; i++)
{
    bool isEqual = a == int.Parse(b);
}

watch1.Stop();

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

for (int i = 1; i < 1000000; i++)
{
    bool isEqual = a.ToString() == b;
}

watch2.Stop();

Console.WriteLine("Option 1: {0} ms", watch1.Elapsed);
Console.WriteLine("Option 2: {0} ms", watch2.Elapsed);

BTW the answer is the second option.

Community
  • 1
  • 1
oonyalo
  • 466
  • 1
  • 6
  • 12
  • 12
    Have you performed any benchmarks? – Elliott Frisch Nov 19 '13 at 19:46
  • 1
    as a guess: I would take the second one, because it cannot fail. int.Parse can fail and throw an exception. Sure, you can use tryparse, but the overhead would probably kill the performance. – Christian Sauer Nov 19 '13 at 19:49
  • I suspect converting to string is faster, but the only way to know for sure is to benchmark it... – Thomas Levesque Nov 19 '13 at 19:49
  • 5
    I am sure there are bigger bottlenecks within your code than this specific scenario. – Arran Nov 19 '13 at 19:49
  • 1
    option 2 performs faster than first one. – Chandan Kumar Nov 19 '13 at 19:49
  • 3
    Parsing is harder than printing in general. But if you do do a lot, (a) why, and (b) is it even a bottleneck, and (c) measure. – Nicholas W Nov 19 '13 at 19:49
  • 1
    @NicholasW Not necessarily. Parsing can be performed with just addition and multiplication, while converting to string will probably require divisions and modulo. There's also allocation of integers vs an array, etc. After the conversion, comparison of integers would also surely be much faster. – Zong Nov 19 '13 at 19:52
  • Though not related to performance, I'd opt for version one as comparing ints is more stable than comparing strings. I suspect that it is slower, but I don't think that the performance difference would be notable. – Markus Nov 19 '13 at 19:55
  • 1
    You wrote the code; if you want to know how fast it runs consider running it. – Eric Lippert Nov 19 '13 at 20:52
  • @Arran Yes, there are, I was just curious. – oonyalo Nov 19 '13 at 21:13
  • @NicholasW (a) for example, I get strings from things like url query parameters or user control values and compare them to integers in an object, (b) no it's not a bottleneck, I was just curious, and (c) duly noted. – oonyalo Nov 19 '13 at 21:22

1 Answers1

3

A few minutes of work and you can benchmark this yourself reasonably enough to see the difference.

1.) Create a general purpose timing routine.

  public void RunTest(Action action, String name, Int32 iterations)
  {
      var sw = new System.Diagnostics.Stopwatch();
      System.GC.Collect();
      System.GC.WaitForPendingFinalizers();

      sw.Start();

      for(var i = 0; i<iterations; i++)
      {
          action();
      }

      sw.Stop();

      Console.Write("Name: {0},", name);
      Console.Write(" Iterations: {1},", iterations);
      Console.WriteLine(" Milliseconds: {2}", sw.ElapsedMilliseconds);
  }

2.) Create your two test functions.

  public void CompareWithParseInt()
  {
      int a = 1;
      string b = "1";
      bool isEqual = a == int.Parse(b);
  }
  public void CompareWithToString()
  {
      int a = 1;
      string b = "1";
      bool isEqual = a.ToString() == b;
  }

3.) Now benchmark the crap out of them.

RunTest(CompareWithParseInt, "Compare With ParseInt", 1);
//Name: Compare With ParseInt, Iterations: 1, Milliseconds: 0
RunTest(CompareWithParseInt, "Compare With ParseInt", 1);
//Name: Compare With ParseInt, Iterations: 1, Milliseconds: 0
RunTest(CompareWithParseInt, "Compare With ParseInt", 10);
//Name: Compare With ParseInt, Iterations: 10, Milliseconds: 0
RunTest(CompareWithParseInt, "Compare With ParseInt", 100);
//Name: Compare With ParseInt, Iterations: 100, Milliseconds: 0
RunTest(CompareWithParseInt, "Compare With ParseInt", 1000);
//Name: Compare With ParseInt, Iterations: 1000, Milliseconds: 0
RunTest(CompareWithParseInt, "Compare With ParseInt", 100000);
//Name: Compare With ParseInt, Iterations: 100000, Milliseconds: 12
RunTest(CompareWithParseInt, "Compare With ParseInt", 1000000);
//Name: Compare With ParseInt, Iterations: 1000000, Milliseconds: 133
RunTest(CompareWithToString, "Compare With ToString", 1000000);
//Name: Compare With ToString, Iterations: 1000000, Milliseconds: 112
RunTest(CompareWithToString, "Compare With ToString", 100000000);
//Name: Compare With ToString, Iterations: 100000000, Milliseconds: 10116
RunTest(CompareWithParseInt, "Compare With ParseInt", 100000000);
//Name: Compare With ParseInt, Iterations: 100000000, Milliseconds: 12447

Conclusion:

As you can see in this particular case, you can pretty much do whatever makes you happy because if there is a bottleneck in your application. It's not with the above code :)

Josh
  • 44,706
  • 7
  • 102
  • 124
  • 1
    This is a nice piece of code, reusable too! :) – RealityDysfunction Nov 19 '13 at 20:12
  • The title to this question should be changed to "How to benchmark?" :) – Steve Nov 19 '13 at 20:59
  • After Elliot Frisch's comment I did something similar to this: http://stackoverflow.com/a/15108875/629211 but yours works too. I know there isn't a big difference, I was just curious. – oonyalo Nov 19 '13 at 21:11
  • For the record this approach includes the JIT compilation as part of the timing. To get a more accurate timing of the method under test, you should make sure that it has already been JIT compiled before timing it. – Brian Rasmussen Nov 19 '13 at 21:13