为什么在使用strtok之前使用strchr会加快运行时间?

4

我有这段代码:

void
fill_array (unsigned int *iarray, char *string, int max)
{
  int ipos = 0;
  char *iholder;

  iholder = strtok (string, ",");
  while (iholder != NULL)
    {
      iarray[ipos++] = atoi (iholder);
      if (ipos == max)
    {
      return;
    }
      iholder = strtok (NULL, ",");
    }

}

例如,它需要一个字符串"1,2,3,4",并将数字输入到数组中。我将其放在一个循环中,并获得了3.3秒的运行时间。

使用以下代码:

void
fill_array (unsigned int *iarray, char *string, int max)
{
  int ipos = 0;
  char *iholder;
  if (!strchr (string, ','))
    {
      iarray[0] = atoi (string);
      return;
    }
  iholder = strtok (string, ",");
  while (iholder != NULL)
    {
      iarray[ipos++] = atoi (iholder);
      if (ipos == max)
    {
      return;
    }
      iholder = strtok (NULL, ",");
    }

}

执行时间约为1.4秒。

唯一的区别是我插入了strchr,只是为了看它是否能在单个数字上运行得更快,但由于某种原因,在较长列表上运行得更快。

有人能解释为什么吗?

我正在使用以下代码进行测试:

int main ()
{
  unsigned int iarray[5];
  char str_test[] = "56,75,22,83";
  int i;
  struct timeval start;
  struct timeval end;

  gettimeofday (&start, NULL);


  for (i = 0; i < 10000000; i++)
    {
      fill_array (iarray, str_test, 5);
    }

  gettimeofday (&end, NULL);
  if (end.tv_usec - start.tv_usec < 0)
    {
      end.tv_usec += 1000000L;
      end.tv_sec -= 1;
    }

  printf ("Runtime: %ld s %03ld ms\n",
      end.tv_sec - start.tv_sec, (end.tv_usec - start.tv_usec) / 1000);

  return 0;
}
2个回答

2

看起来很奇怪?您是在同一台机器上测试两个代码吗?您取样多少次?您用于计算时间的代码是什么?请分享。


我在Windows上使用Dev-c++和Debian机器进行了测试,通过添加strchr,两者都获得了更快的运行时间。 - ZPS
你是使用性能分析器来测量时间,还是自己编写了一些代码?如果是这样,请分享一下。 - Muhammad Ummar
@ZPS,记住strtok会修改你传递的字符串内容,而且由于你一遍又一遍地传递同一个字符串,所以我认为在第一次执行后,传递的字符串将不再包含实际值“56,75,22,83”。测试一下,也打印一下string参数的内容,并循环少一些时间进行调试,比如只循环2次。 - Muhammad Ummar
是的,你说得对,Ummar。我将传递的字符串复制到一个临时变量中,然后再次运行了测试。结果如预期一样。 - ZPS

2

你的代码中第一个strchr函数可能会让程序提前退出,以减少需要处理的内容?


这正是我所想的,但我打印出了数组,它填满了列表中的所有数字。 - ZPS
似乎不正确,如果传入“1,2,3,4”,它将永远不会在strchr检查中出现。理论上,这应该需要更多的时间来处理一个额外的函数调用。 - Muhammad Ummar
1
我很愚蠢,错过了显而易见的事情。strtok会修改传递给它的字符串。第一次通过后,在那个strchr之后就会退出。 - ZPS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接