【问题标题】:Performance difference between converting an int to a string or a string to an int [closed]将 int 转换为字符串或将字符串转换为 int 之间的性能差异 [关闭]
【发布时间】:2013-11-19 19:45:29
【问题描述】:

我在字符串和整数之间做了很多比较,想知道两者中哪一个提供更好的性能。

这个:

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

或者这个:

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

编辑:在 Elliott Frisch 发表评论后,我编写了以下代码进行基准测试,我从中得到:https://stackoverflow.com/a/15108875/629211。接受的答案也有效。

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

顺便说一句,答案是第二种选择。

【问题讨论】:

  • 您是否执行过任何基准测试?
  • 作为一个猜测:我会选择第二个,因为它不会失败。 int.Parse 可能会失败并引发异常。当然,您可以使用 tryparse,但开销可能会影响性能。
  • 我确信您的代码中存在比这个特定场景更大的瓶颈。
  • 选项 2 的执行速度比第一个快。
  • 解析通常比打印更难。但如果你做了很多,(a)为什么,(b)它是否甚至是瓶颈,以及(c)衡量。

标签: c# .net


【解决方案1】:

只需几分钟的工作,您就可以自己合理地对其进行基准测试,以了解其中的差异。

1.) 创建通用计时例程。

  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.) 创建两个测试函数。

  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.) 现在对它们进行基准测试。

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

结论:

正如您在本例中所见,您几乎可以做任何让您开心的事情,因为如果您的应用程序存在瓶颈。不是上面的代码:)

【讨论】:

  • 这是一段不错的代码,也可以重用! :)
  • 此问题的标题应更改为“如何进行基准测试?” :)
  • 在 Elliot Frisch 发表评论后,我做了类似的事情:stackoverflow.com/a/15108875/629211 但你的也可以。我知道差别不大,我只是好奇。
  • 为了记录,这种方法包括 JIT 编译作为计时的一部分。为了获得更准确的被测方法计时,您应该确保在计时之前已经对其进行了 JIT 编译。
猜你喜欢
  • 2013-03-02
  • 2019-07-16
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
  • 2011-03-06
  • 1970-01-01
相关资源
最近更新 更多