【问题标题】:Calculation time elapsed by a particular function in C programC程序中特定函数经过的计算时间
【发布时间】:2015-03-14 20:04:05
【问题描述】:

我有一个代码,我想在其中计算两种排序算法合并排序和快速排序以微秒或更精确的时间对 N 个数字进行排序所花费的时间。 这样计算出来的两次,然后我们将输出到终端。 代码(部分代码):

printf("THE LIST BEFORE SORTING IS(UNSORTED LIST):\n");
printlist(arr,n);
mergesort(extarr,0,n-1);
printf("THE LIST AFTER SORTING BY MERGE SORT IS(SORTED LIST):\n");
printlist(extarr,n);
quicksort(arr,0,n-1);
printf("THE LIST AFTER SORTING BY QUICK SORT IS(SORTED LIST):\n");
printlist(arr,n);

通过提供它将如何完成来帮助我。我已经尝试通过将两个变量作为开始停止并将它们分别保持在函数调用的上方和下方来尝试 clock_t 但这根本没有帮助并且总是将其差异打印为零. 请建议一些其他方法或功能,记住它在任何类型的操作系统中运行都没有问题。 感谢您提前提供任何帮助。

【问题讨论】:

    标签: c timer clock


    【解决方案1】:

    方法:1

    计算程序花费的总时间你可以使用linux实用程序“时间”。

        Lets your program name is test.cpp.
        $g++ -o test test.cpp
        $time ./test
    
        Output will be like :
        real    0m11.418s
        user    0m0.004s
        sys 0m0.004s
    

    方法:2

    您也可以使用linux profiling方法“gprof”通过不同的函数来查找时间。

    首先你必须用“-pg”标志编译程序。

        $g++ -pg -o test test.cpp
        $./test
        $gprof test gmon.out
    

    PS : gmon.out 是 gprof 创建的默认文件

    【讨论】:

      【解决方案2】:

      您可以在 Linux 中调用 gettimeofday 函数,在 Windows 中调用 timeGetTime。在调用排序函数之前和调用排序函数之后调用这些函数并取差。

      请查看手册页以获取更多详细信息。如果您仍然无法获得一些有形数据(由于较小的数据集,所花费的时间可能太小),最好尝试一起测量“n”次迭代的时间,然后推断单次运行的时间或者增加要排序的数据集的大小。

      【讨论】:

      • 给你一个很好的例子,包括如何计算 gettimeofday() 返回的 2 个 timeval 结构的差异。 mpp.mpg.de/~huber/util/timevaldiff.c
      • @jay 我想制作一个可以在两个操作系统中运行的程序。不希望如果我运行这个操作系统而不是必须这样做,如果我运行那个操作系统而不是必须这样做
      • 不幸的是,在使用系统调用时没有办法解决这个问题。 Windows 不支持完整的 POSIX 标准,因此您将不得不求助于不同的系统调用/接口。
      • @Troy 对于运行时间小于1000 微秒的循环,函数timevaldiff 将返回0
      【解决方案3】:

      不确定您是否尝试过以下操作。我知道您的原始帖子说您已尝试使用CLOCKS_PER_SEC。使用CLOCKS_PER_SEC 并执行(stop-start)/CLOCKS_PER_SEC 将使您获得秒数。双精度将提供更高的精度。

      #include <time.h>
      
      main()
      {
      clock_t launch = clock();
      //do work
      clock_t done = clock();
      double diff = (done - launch) / CLOCKS_PER_SEC;
      }
      

      【讨论】:

        【解决方案4】:

        得到Zero 的原因可能是您使用的时间源分辨率不佳。这些时间源通常以大约 10 到 20 ms 递增。这很糟糕,但这就是他们的工作方式。当您的排序完成时间少于这个时间增量时,结果将是zero。您可以通过增加系统中断频率将此结果增加到 1 ms 状态。对于 Windows and Linux,没有标准的方法来完成此操作。他们有自己的方式。 通过高频计数器可以获得更高的分辨率。 Windows 和 Linux 确实提供了对此类计数器的访问,但同样,代码看起来可能略有不同。

        如果您应该让one piece of codewindows and linux 上运行,我建议您循环执行时间测量。运行代码以循环测量数百次甚至更多次 并捕获循环外的时间。将捕获的时间除以循环周期数并得到结果。

        当然:这仅用于评估。您不想在最终代码中使用它。 并且: 考虑到时间分辨率在 1 到 20 毫秒之间,您应该对总时间做出一个很好的选择,以获得合适的测量分辨率。 (提示:调整循环计数,让它至少持续一秒钟左右。)

        示例:

        clock_t start, end;
        
        printf("THE LIST BEFORE SORTING IS(UNSORTED LIST):\n");
        printlist(arr,n);
        
        start = clock();
        for(int i = 0; i < 100; i++){ 
          mergesort(extarr,0,n-1);
        }
        end   = clock();
        double diff = (end - start) / CLOCKS_PER_SEC;
        
        // and so on...
        
        printf("THE LIST AFTER SORTING BY MERGE SORT IS(SORTED LIST):\n");
        printlist(extarr,n);
        quicksort(arr,0,n-1);
        printf("THE LIST AFTER SORTING BY QUICK SORT IS(SORTED LIST):\n");
        printlist(arr,n);
        

        【讨论】:

          【解决方案5】:

          如果您使用的是 Linux 2.6.26 或更高版本,那么 getrusage(2) 是最准确的方法:

          #include <sys/time.h>
          #include <sys/resource.h>
          
          // since Linux 2.6.26
          // The macro is not defined in all headers, but supported if your Linux version matches
          #ifndef RUSAGE_THREAD
          #define RUSAGE_THREAD 1
          #endif
          // If you are single-threaded then RUSAGE_SELF is POSIX compliant 
          // http://linux.die.net/man/2/getrusage
          
          struct rusage rusage_start, rusage_stop;
          
          getrusage(RUSAGE_THREAD, &rusage_start);
          
          ...
          
          getrusage(RUSAGE_THREAD, &rusage_stop);
          
          // amount of microseconds spent in user space
          size_t user_time = ((rusage_stop.ru_utime.tv_sec - rusage_start.ru_stime.tv_sec) * 1000000) + rusage_stop.ru_utime.tv_usec - rusage_start.ru_stime.tv_usec;
          // amount of microseconds spent in kernel space
          size_t system_time = ((rusage_stop.ru_stime.tv_sec - rusage_start.ru_stime.tv_sec) * 1000000) + rusage_stop.ru_stime.tv_usec - rusage_start.ru_stime.tv_usec;
          

          【讨论】:

            猜你喜欢
            • 2020-04-12
            • 1970-01-01
            • 2010-11-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多