测量R和C ++中执行时间的类似方法

时间:2016-07-26 05:47:12

标签: c++ r similarity execution-time

在R中测量执行时间的哪种方法与C ++中的方法clock()最相似?

我使用sys.time()。

如果我可以将C ++编程语言中的执行时间与R进行比较,您认为怎么样?

1 个答案:

答案 0 :(得分:0)

有两种方法可以回答。

第一个(简短的)

要在R中获得执行语句或代码块的时间,可以使用'system.time'。在规范中 - “返回使用expr的CPU(和其他)时间”。 - 它在C ++中接近clock(),因为标准表示时钟 - “返回程序消耗的处理器时间。”

所以,我的答案是:您可以比较C ++(带时钟)和R(带system.time())的执行时间。

第二次(很长)

我已经选择 R-3.3.1.tar.gz 文件,并在文件夹 src 中为一些看似与此问题相关的文件提供资金。

在档案system.c(声明)中:

 void R_setStartTime(void); /* in sys-unix.c */

在档案in sys-unix.c(定义)中:

void R_setStartTime(void)
{
#ifdef HAVE_SYSCONF
    clk_tck = (double) sysconf(_SC_CLK_TCK);
#else
# ifndef CLK_TCK
/* this is in ticks/second, generally 60 on BSD style Unix, 100? on SysV
 */
#  ifdef HZ
#   define CLK_TCK HZ
#  else
#   define CLK_TCK 60
#  endif
# endif /* not CLK_TCK */
    clk_tck = (double) CLK_TCK;
#endif
    /* printf("CLK_TCK = %d\n", CLK_TCK); */
    StartTime = currentTime();
}

/* NOTE
   This used to use times() for elapsed times, which is measured in
   clock ticks (which can overflow).  It is possible this version uses
   time() and so is in seconds.  But even Cygwin has gettimeofday.
 */
attribute_hidden
void R_getProcTime(double *data)
{
    /* docs say this is rounded to the nearest ms */
    double et = currentTime() - StartTime;
    data[2] = 1e-3 * rint(1000*et);
#ifdef HAVE_GETRUSAGE
    /* all known current OSes */
    struct rusage self, children;
    getrusage(RUSAGE_SELF, &self);
    getrusage(RUSAGE_CHILDREN, &children);
    data[0] = (double) self.ru_utime.tv_sec +
    1e-3 * (self.ru_utime.tv_usec/1000);
    data[1] = (double) self.ru_stime.tv_sec +
    1e-3 * (self.ru_stime.tv_usec/1000);
    data[3] = (double) children.ru_utime.tv_sec +
    1e-3 * (children.ru_utime.tv_usec/1000);
    data[4] = (double) children.ru_stime.tv_sec +
    1e-3 * (children.ru_stime.tv_usec/1000);
#else
    /* Not known to be currently used */
    struct tms timeinfo;
    times(&timeinfo);
    data[0] = fround(timeinfo.tms_utime / clk_tck, 3);
    data[1] = fround(timeinfo.tms_stime / clk_tck, 3);
    data[3] = fround(timeinfo.tms_cutime / clk_tck, 3);
    data[4] = fround(timeinfo.tms_cstime / clk_tck, 3);
#endif
}

currentTime()中定义的times.c如下:

double currentTime(void)
{
    double ans = NA_REAL;

#ifdef HAVE_TIMESPEC_GET
    struct timespec tp;
    int res = timespec_get(&tp, TIME_UTC);
    if(res != 0)
    ans = (double) tp.tv_sec + 1e-9 * (double) tp.tv_nsec;
#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
    /* Has 2038 issue if time_t: tv.tv_sec is 32-bit. */
    struct timespec tp;
    int res = clock_gettime(CLOCK_REALTIME, &tp);
    if(res == 0)
    ans = (double) tp.tv_sec + 1e-9 * (double) tp.tv_nsec;

#elif defined(HAVE_GETTIMEOFDAY)
    /* Mac OS X, mingw.org, used on mingw-w64.
       Has 2038 issue if time_t: tv.tv_sec is 32-bit.
     */
    struct timeval tv;
    int res = gettimeofday(&tv, NULL);
    if(res == 0)
    ans = (double) tv.tv_sec + 1e-6 * (double) tv.tv_usec;

#else
    /* No known current OSes */
    time_t res = time(NULL);
    if(res != (time_t)(-1)) /* -1 must be an error as the real value -1
                   was ca 1969 */
    ans = (double) res;
#endif

#ifndef HAVE_POSIX_LEAPSECONDS
    /* No known current OSes */
    /* Disallowed by POSIX (1988-):
       http://www.mail-archive.com/leapsecs@rom.usno.navy.mil/msg00109.html
       https://en.wikipedia.org/wiki/Unix_time
    */
    if (!ISNAN(ans)) {
    ans -= n_leapseconds;
    }
#endif
    return ans;
}

因此,我们可以看到R中时间检测的实现完全取决于平台。例如,times.c开头的注释解释了:

  

功能时钟()是C99,在time.h中定义。它测量CPU       在CLOCKS_PER_SEC的时间:整数有一个小的危险       溢出。

     

函数times()是POSIX并在sys/times.h中定义。它       返回以时钟周期为单位的经过时间,以及a中的CPU时间       struct tms *参数(也在时钟滴答中)。

答案是:测量方法可能不同,但测量单位和测量值的定义方式相同,因此无关紧要,clock()C99或{{1根据POSIX - 这是CPU时间。