首页 > 解决方案 > How to create recursion for vector addition?

问题描述

I need help with this code problem, if anyone had a similar problem it would help me a lot. It is necessary to write a program that loads a natural number n, two vectors of dimensions n, and then prints a sum of loaded vector. The calculation of the sum of two vectors should be performed in a recursive function whose prototype is:

 void saberi(double *vector_a,double *vector_b,double *vector_res,int n)

I did it until the part when the recursion should be done, I don't know how to do it, so any help would be welcome.

My code now:

#include <stdio.h>
#include <stdlib.h>
#define MAX 100

void sum(double *vector_a,double *vector_b,double *vector_res,int n)
{

}
int main()
{
   int n;
   int sum;
   double a[MAX],b[MAX],c[MAX];
   printf("Insert dimension of vector (n):\n");
   scanf("%d",&n);
   printf("Insert a element of vector a:\n");
   int i;
   for(i=1;i<=n;i++)
   {
     scanf("%d",a[i]);
   }
   printf("Insert a element of vector b:\n");
   for(i=1;i<=n;i++)
   {
       scanf("%d",b[i]);
   }
   for(i=1;i<=n;i++)
   {
       result=sum(a,b,result,n);
   }
   for(i=1;i<=n;i++)
   {
       printf("%d",result);
   }
}

Thanks in advance ! Best regards :)

标签: crecursion

解决方案


同意CiaPan 的评论 [递归使用不当]。

但是,给定柠檬,我们可以制作柠檬水。

有一些古老的格言 [来自 Kernighan 和 Plauger 的“编程风格元素”]:

  1. 在加快速度之前先做好准备
  2. 当你让它更快时保持正确
  3. 在加快速度之前先说清楚

因此,我们应该首先创建更简单的迭代解决方案。然后我们可以使用它作为对新的“更快”版本的交叉检查[在我们这里的例子中,递归解决方案]。

因此,我们可以制作一个诊断测试套件/程序来比较结果 [见下文]。

通常,当我们有工作代码但代码太慢并且我们需要更快的版本时,这种技术是一种很好的使用方法。或者,代码很繁琐,应该重构为更简单/更清晰/更干净。

此外,如果我们试图让代码更快,我们应该测量原始代码和“更快”代码的速度,以确保我们实际上让代码更快[而且,讽刺的是,更慢]。


首先有一些错误:

迭代i = 1; i <= n; ++i而不是i = 0; i < n; ++i. 这会导致 UB [未定义行为],因为我们没有更改元素 0 并超出数组的末尾。

错误是因为scanf我们想要而%lf不是。而且,我们想要:而不是. 如果我们使用这些进行编译,编译器会对其进行标记。 %d&vector_a[i] vector_a[i]-Wall

sum函数试图从void函数返回一个地址。

它在循环中被调用,但函数本身应该执行循环。

这是一个带注释的版本。

我使用cpp条件来表示旧代码与新代码:

#if 0
// old code
#else
// new code
#endif

无论如何,这是代码:

#include <stdio.h>
#include <stdlib.h>
#define MAX 100

void
sum(double *vector_a, double *vector_b, double *vector_rez, int n)
{
#if 0
    if (n == 0)
        return 0;
    else
        return vector_res = vector_a + vector_b;
#else
    for (int idx = 0;  idx < n;  ++idx)
        vector_rez[idx] = vector_a[idx] + vector_b[idx];
#endif
}

int
main()
{
    int n;
#if 0
    int result;
#endif
    double vector_a[MAX];
    double vector_b[MAX];
// NOTE/BUG: the code below uses vector_res and _not_ vector_rez
#if 0
    double vector_rez[MAX];
#else
    double vector_res[MAX];
#endif

    printf("Insert dimension of vector (n):\n");
    scanf("%d", &n);
    int i;

// NOTE/BUG: vectors start at index 0 and _not_ 1 -- this is an issue for _all_
// for loops below

// NOTE/BUG: we want "%lf" and _not_ "%d"
// NOTE/BUG: we want (e.g.) &vector_a[i] (a pointer to the element) and _not_
// vector_a[i] (the value of the vector element)
#if 0
    printf("Insert element of vector a:\n");
    for (i = 1; i <= n; i++) {
        scanf("%d", vector_a[i]);
    }
    printf("Insert element of vector b:\n");
    for (i = 1; i <= n; i++) {
        scanf("%d", vector_b[i]);
    }
#else
    printf("Insert element of vector a:\n");
    for (i = 0; i < n; i++) {
        scanf("%lf", &vector_a[i]);
    }
    printf("Insert element of vector b:\n");
    for (i = 0; i < n; i++) {
        scanf("%lf", &vector_b[i]);
    }
#endif

// NOTE/BUG: we want the loop to be in the sum function and _not_ here
// otherwise, why pass down vector_res
#if 0
    for (i = 1; i <= n; i++) {
        vector_res[i] = sum(vector_a, vector_b, vector_res, n);
    }
#else
    sum(vector_a,vector_b,vector_res,n);
#endif

#if 0
    for (i = 1; i <= n; i++) {
        printf("%d", vector_res[i]);
    }
#else
    for (i = 0; i < n; i++)
        printf(" %f\n", vector_res[i]);
#endif

    return 0;
}

这是一个实现迭代函数和递归函数的重构版本。

请注意,迭代版本 ( sumiter) 从 0 迭代到n - 1[这是缓存友好的]。

但是,对于递归版本 ( sumcall),我们不能这样做。我们需要一个额外的参数,即当前索引 [除了n参数]。

所以,我们必须从n - 10 求和。

这是一个运行测试并比较两个函数的正确性的版本,如果递归函数与迭代函数不匹配(即我们正在应用上述格言),则中止:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX 100

// sumiter -- sum vectors [iterative]
void
sumiter(double *vector_a, double *vector_b, double *vector_rez, int n)
{
    for (int idx = 0;  idx < n;  ++idx)
        vector_rez[idx] = vector_a[idx] + vector_b[idx];
}

// sumcall -- sum vectors [recursive]
void
sumcall(double *vector_a, double *vector_b, double *vector_rez, int idx)
{

    --idx;
    if (idx < 0)
        return;

    vector_rez[idx] = vector_a[idx] + vector_b[idx];

    sumcall(vector_a,vector_b,vector_rez,idx);
}

void
randvec(double *vec,int n)
{

    for (int idx = 0;  idx < n;  ++idx)
        vec[idx] = drand48();
}

double
tscgetf(void)
{
    struct timespec ts;
    double sec;

    clock_gettime(CLOCK_MONOTONIC,&ts);
    sec = ts.tv_nsec;
    sec /= 1e9;
    sec += ts.tv_sec;

    return sec;
}

double
dofnc(void (*fnc)(double *a, double *b, double *rez, int n),
    double *a,double *b,double *res,int n)
{
    double elap_best = 1e9;

    for (int iter = 1;  iter <= 5;  ++iter) {
        double elap_beg = tscgetf();

        fnc(a,b,res,n);

        double elap_end = tscgetf();
        elap_end -= elap_beg;

        if (elap_end < elap_best)
            elap_best = elap_end;
    }

    return elap_best;
}

void
dotest(int n)
{
    double vector_a[MAX];
    double vector_b[MAX];
    double res_iter[MAX];
    double res_call[MAX];
    int stopflg = 0;

    if (n > MAX)
        n = MAX;

    randvec(vector_a,n);
    randvec(vector_b,n);

    double elap_iter = dofnc(sumiter,vector_a,vector_b,res_iter,n);
    double elap_call = dofnc(sumcall,vector_a,vector_b,res_call,n);

    // show elapsed time
    printf("ITER: %.9f\n",elap_iter);
    printf("CALL: %.9f\n",elap_call);

    for (int idx = 0;  idx < n;  ++idx) {
        int miss = (res_call[idx] != res_iter[idx]);
        if (miss)
            stopflg = 1;
        printf("dotest: %d %f %f%s\n",
            idx,res_iter[idx],res_call[idx],miss ? " (FAIL)" : "");
    }

    printf("dotest: %s\n",stopflg ? "FAIL" : "PASS");

    if (stopflg)
        exit(1);
}

int
main(void)
{

    dotest(20);
    dotest(67);
    dotest(MAX);

    return 0;
}

这是程序输出:

ITER: 0.000000042
CALL: 0.000000043
dotest: 0 0.875981 0.875981
dotest: 1 0.532542 0.532542
dotest: 2 0.961892 0.961892
dotest: 3 0.692074 0.692074
dotest: 4 1.175032 1.175032
dotest: 5 0.279751 0.279751
dotest: 6 0.978612 0.978612
dotest: 7 1.057831 1.057831
dotest: 8 0.603525 0.603525
dotest: 9 1.269707 1.269707
dotest: 10 1.218069 1.218069
dotest: 11 0.949643 0.949643
dotest: 12 1.825637 1.825637
dotest: 13 1.352543 1.352543
dotest: 14 0.657011 0.657011
dotest: 15 0.304143 0.304143
dotest: 16 0.786893 0.786893
dotest: 17 0.397292 0.397292
dotest: 18 0.931237 0.931237
dotest: 19 0.979120 0.979120
dotest: PASS
ITER: 0.000000101
CALL: 0.000000100
dotest: 0 1.481146 1.481146
dotest: 1 0.972322 0.972322
dotest: 2 1.381247 1.381247
dotest: 3 0.592519 0.592519
dotest: 4 1.486516 1.486516
dotest: 5 0.904968 0.904968
dotest: 6 1.032588 1.032588
dotest: 7 0.514809 0.514809
dotest: 8 1.450355 1.450355
dotest: 9 0.986021 0.986021
dotest: 10 1.501674 1.501674
dotest: 11 0.510463 0.510463
dotest: 12 1.486773 1.486773
dotest: 13 1.279277 1.279277
dotest: 14 1.299667 1.299667
dotest: 15 0.793899 0.793899
dotest: 16 1.487031 1.487031
dotest: 17 1.552800 1.552800
dotest: 18 0.616313 0.616313
dotest: 19 0.993808 0.993808
dotest: 20 1.286723 1.286723
dotest: 21 1.249075 1.249075
dotest: 22 0.083708 0.083708
dotest: 23 1.575160 1.575160
dotest: 24 1.126545 1.126545
dotest: 25 0.264593 0.264593
dotest: 26 0.795436 0.795436
dotest: 27 0.973021 0.973021
dotest: 28 0.985016 0.985016
dotest: 29 1.752784 1.752784
dotest: 30 0.852236 0.852236
dotest: 31 1.499697 1.499697
dotest: 32 1.423587 1.423587
dotest: 33 0.924229 0.924229
dotest: 34 1.271571 1.271571
dotest: 35 1.573766 1.573766
dotest: 36 1.548978 1.548978
dotest: 37 1.732789 1.732789
dotest: 38 1.085471 1.085471
dotest: 39 0.483692 0.483692
dotest: 40 1.030894 1.030894
dotest: 41 0.286513 0.286513
dotest: 42 0.872451 0.872451
dotest: 43 1.230225 1.230225
dotest: 44 1.251257 1.251257
dotest: 45 1.282516 1.282516
dotest: 46 0.557632 0.557632
dotest: 47 0.824636 0.824636
dotest: 48 0.507834 0.507834
dotest: 49 0.303870 0.303870
dotest: 50 0.021515 0.021515
dotest: 51 0.431755 0.431755
dotest: 52 0.623890 0.623890
dotest: 53 0.596018 0.596018
dotest: 54 0.552220 0.552220
dotest: 55 0.959291 0.959291
dotest: 56 1.667865 1.667865
dotest: 57 1.216065 1.216065
dotest: 58 0.346906 0.346906
dotest: 59 0.973154 0.973154
dotest: 60 1.073773 1.073773
dotest: 61 1.070332 1.070332
dotest: 62 0.723126 0.723126
dotest: 63 1.371606 1.371606
dotest: 64 1.053194 1.053194
dotest: 65 0.266924 0.266924
dotest: 66 1.266108 1.266108
dotest: PASS
ITER: 0.000000135
CALL: 0.000000134
dotest: 0 1.224731 1.224731
dotest: 1 1.549801 1.549801
dotest: 2 0.210620 0.210620
dotest: 3 1.821897 1.821897
dotest: 4 0.239412 0.239412
dotest: 5 0.245666 0.245666
dotest: 6 0.306005 0.306005
dotest: 7 0.435580 0.435580
dotest: 8 1.439958 1.439958
dotest: 9 1.330953 1.330953
dotest: 10 0.962920 0.962920
dotest: 11 1.129370 1.129370
dotest: 12 0.979000 0.979000
dotest: 13 1.271833 1.271833
dotest: 14 1.180285 1.180285
dotest: 15 1.115377 1.115377
dotest: 16 1.379975 1.379975
dotest: 17 1.083476 1.083476
dotest: 18 0.916506 0.916506
dotest: 19 0.521584 0.521584
dotest: 20 1.725734 1.725734
dotest: 21 1.514879 1.514879
dotest: 22 0.513368 0.513368
dotest: 23 0.696086 0.696086
dotest: 24 0.969453 0.969453
dotest: 25 0.540273 0.540273
dotest: 26 1.479472 1.479472
dotest: 27 0.222709 0.222709
dotest: 28 0.334622 0.334622
dotest: 29 0.878528 0.878528
dotest: 30 1.122719 1.122719
dotest: 31 1.244526 1.244526
dotest: 32 1.394182 1.394182
dotest: 33 1.225557 1.225557
dotest: 34 1.530945 1.530945
dotest: 35 1.604853 1.604853
dotest: 36 0.895270 0.895270
dotest: 37 1.279060 1.279060
dotest: 38 0.052540 0.052540
dotest: 39 0.273471 0.273471
dotest: 40 0.969764 0.969764
dotest: 41 1.071431 1.071431
dotest: 42 0.359576 0.359576
dotest: 43 0.718445 0.718445
dotest: 44 1.692190 1.692190
dotest: 45 1.497816 1.497816
dotest: 46 0.675670 0.675670
dotest: 47 1.031740 1.031740
dotest: 48 0.572276 0.572276
dotest: 49 0.905983 0.905983
dotest: 50 0.266687 0.266687
dotest: 51 0.471825 0.471825
dotest: 52 0.462346 0.462346
dotest: 53 1.157948 1.157948
dotest: 54 0.928059 0.928059
dotest: 55 0.931817 0.931817
dotest: 56 1.389035 1.389035
dotest: 57 1.416517 1.416517
dotest: 58 1.217675 1.217675
dotest: 59 0.991833 0.991833
dotest: 60 1.259813 1.259813
dotest: 61 0.070612 0.070612
dotest: 62 0.493996 0.493996
dotest: 63 0.514937 0.514937
dotest: 64 1.429208 1.429208
dotest: 65 1.490289 1.490289
dotest: 66 1.497546 1.497546
dotest: 67 1.074150 1.074150
dotest: 68 1.325306 1.325306
dotest: 69 0.775838 0.775838
dotest: 70 0.988785 0.988785
dotest: 71 1.261825 1.261825
dotest: 72 0.228171 0.228171
dotest: 73 0.196502 0.196502
dotest: 74 0.711210 0.711210
dotest: 75 0.571607 0.571607
dotest: 76 1.758753 1.758753
dotest: 77 0.745936 0.745936
dotest: 78 1.226576 1.226576
dotest: 79 1.027937 1.027937
dotest: 80 1.486168 1.486168
dotest: 81 1.097114 1.097114
dotest: 82 0.666452 0.666452
dotest: 83 1.070599 1.070599
dotest: 84 0.505941 0.505941
dotest: 85 1.424329 1.424329
dotest: 86 1.514565 1.514565
dotest: 87 0.915301 0.915301
dotest: 88 1.000928 1.000928
dotest: 89 1.060346 1.060346
dotest: 90 1.687241 1.687241
dotest: 91 0.270245 0.270245
dotest: 92 1.195685 1.195685
dotest: 93 1.040315 1.040315
dotest: 94 0.580820 0.580820
dotest: 95 0.988709 0.988709
dotest: 96 0.185577 0.185577
dotest: 97 1.299616 1.299616
dotest: 98 1.727305 1.727305
dotest: 99 0.105829 0.105829
dotest: PASS

更新:

如果您在递归调用之后进行添加,正如我在伪代码中提出的那样,对向量的操作将向上,即朝着缓存友好的方向发展。但是,调用堆栈管理成本可能会掩盖差异。

好吧,让我们测试一下...

我已经增强了测试,以便它可以将许多不同的函数与更大的向量进行比较。

我已经添加了你的测试[我认为是你的测试]。

我在下面添加了程序输出。

实际上,您可能对结果不满意。我在下面的评论是在我仔细检查基准结果[并添加堆栈扩展]之前。

奇怪的是,当我编写您的解决方案时,它比我的递归解决方案慢8 倍。我可能编码错误,但它似乎比较好。

我的递归解决方案比迭代解决方案快,这很奇怪。原来那是为了-O2. ,-O3迭代解是最快的。


这是更新的代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <sys/resource.h>

#define MAX     1000000

int opt_v;

// sumiter -- sum vectors [iterative]
void
sumiter(double *vector_a, double *vector_b, double *vector_rez, int n)
{
    for (int idx = 0;  idx < n;  ++idx)
        vector_rez[idx] = vector_a[idx] + vector_b[idx];
}

// sumcall -- sum vectors [recursive]
void
sumcall(double *vector_a, double *vector_b, double *vector_rez, int idx)
{

    --idx;
    if (idx < 0)
        return;

    vector_rez[idx] = vector_a[idx] + vector_b[idx];

    sumcall(vector_a,vector_b,vector_rez,idx);
}

// sumcia -- sum vectors [CiaPan's algorithm]
void
sumcia(double *vector_a, double *vector_b, double *vector_rez, int idx)
{

    --idx;
    if (idx < 0)
        return;

    sumcia(vector_a,vector_b,vector_rez,idx);

    vector_rez[idx] = vector_a[idx] + vector_b[idx];
}

typedef struct {
    void (*fnc_fnc)(double *a, double *b, double *rez, int n);
    const char *fnc_sym;
    double fnc_elap;
    int fnc_best;
} fnc_t;

#define DOFNC(_fnc) \
    { .fnc_fnc = _fnc, .fnc_sym = #_fnc }

fnc_t fnclist[] = {
    DOFNC(sumiter),
    DOFNC(sumcall),
    DOFNC(sumcia),
    { .fnc_fnc = NULL }
};

void *
xmalloc(size_t len)
{
    void *ptr;

    ptr = malloc(len);
    if (ptr == NULL) {
        perror("xmalloc");
        exit(1);
    }

    return ptr;
}

double *
randvec(int n)
{
    double *vec;

    vec = xmalloc(sizeof(*vec) * n);

    for (int idx = 0;  idx < n;  ++idx)
        vec[idx] = drand48();

    return vec;
}

double
tscgetf(void)
{
    struct timespec ts;
    double sec;

    clock_gettime(CLOCK_MONOTONIC,&ts);
    sec = ts.tv_nsec;
    sec /= 1e9;
    sec += ts.tv_sec;

    return sec;
}

void
dofnc(fnc_t *fnc,double *a,double *b,double *res,int n)
{
    double elap_best = 1e9;

    for (int iter = 1;  iter <= 5;  ++iter) {
        double elap_beg = tscgetf();

        fnc->fnc_fnc(a,b,res,n);

        double elap_end = tscgetf();
        elap_end -= elap_beg;

        if (elap_end < elap_best)
            elap_best = elap_end;
    }

    printf("ELAPSED: %.9f (%s)\n",elap_best,fnc->fnc_sym);

    fnc->fnc_elap = elap_best;
}

void
dotest(int n)
{
    int stopflg = 0;

    printf("\n");

    n = (rand() % n) + 1;
    printf("dotest: N %d\n",n);

    double *vector_a = randvec(n);
    double *vector_b = randvec(n);

    double *res_cur = xmalloc(sizeof(*res_cur) * n);
    double *res_old = xmalloc(sizeof(*res_old) * n);

    int cmpflg = 0;
    for (fnc_t *fnc = fnclist;  fnc->fnc_fnc != NULL;  ++fnc, cmpflg = 1) {
        for (int idx = 0;  idx < n;  ++idx)
            res_cur[idx] = 0;

        dofnc(fnc,vector_a,vector_b,res_cur,n);

        if (cmpflg) {
            for (int idx = 0;  idx < n;  ++idx) {
                int miss = (res_cur[idx] != res_old[idx]);
                if (miss)
                    stopflg = 1;
                if (miss || opt_v)
                    printf("dotest: %d %f %f%s\n",
                        idx,res_cur[idx],res_old[idx],miss ? " (FAIL)" : "");
            }

            if (stopflg || opt_v)
                printf("dotest: %s\n",stopflg ? "FAIL" : "PASS");
        }

        if (stopflg)
            exit(1);

        double *tmp = res_cur;
        res_cur = res_old;
        res_old = tmp;
    }

    fnc_t *best = fnclist;
    for (fnc_t *fnc = fnclist;  fnc->fnc_fnc != NULL;  ++fnc) {
        if (fnc->fnc_elap < best->fnc_elap)
            best = fnc;
    }
    best->fnc_best += 1;
    printf("BEST: %s (%d times)\n",best->fnc_sym,best->fnc_best);
    fflush(stdout);

    free(vector_a);
    free(vector_b);
    free(res_cur);
    free(res_old);
}

void *
testall(void *ptr)
{

    dotest(20);
    dotest(67);
    for (int tstno = 1;  tstno <= 20;  ++tstno)
        dotest(MAX);

    return (void *) 0;
}

int
bigstack(void)
{
    pthread_t thread;
    pthread_attr_t attr;

    // allocate a 256MB region for the stack.
    size_t stacksize = 3LL * 1024 * 1024 * 1024;

    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, stacksize);

    int rc = pthread_create(&thread, &attr, testall, NULL);

    if (rc) {
        printf("ERROR: return code from pthread_create() is %d\n", rc);
        return 0;
    }

    pthread_join(thread, NULL);

    return 1;
}

int
main(int argc,char **argv)
{

    --argc;
    ++argv;

    for (;  argc > 0;  --argc, ++argv) {
        char *cp = *argv;
        if (*cp != '-')
            break;

        cp += 2;
        switch (cp[-1]) {
        case 'v':
            opt_v = ! opt_v;
            break;
        }
    }

    bigstack();

    return 0;
}

而且,这是输出-O2

dotest: N 4
ELAPSED: 0.000000033 (sumiter)
ELAPSED: 0.000000032 (sumcall)
ELAPSED: 0.000000044 (sumcia)
BEST: sumcall (1 times)

dotest: N 34
ELAPSED: 0.000000062 (sumiter)
ELAPSED: 0.000000056 (sumcall)
ELAPSED: 0.000000188 (sumcia)
BEST: sumcall (2 times)

dotest: N 692778
ELAPSED: 0.002301515 (sumiter)
ELAPSED: 0.002376126 (sumcall)
ELAPSED: 0.012824440 (sumcia)
BEST: sumiter (1 times)

dotest: N 636916
ELAPSED: 0.001993325 (sumiter)
ELAPSED: 0.002052745 (sumcall)
ELAPSED: 0.011495179 (sumcia)
BEST: sumiter (2 times)

dotest: N 747794
ELAPSED: 0.002486300 (sumiter)
ELAPSED: 0.002439044 (sumcall)
ELAPSED: 0.013481327 (sumcia)
BEST: sumcall (3 times)

dotest: N 238336
ELAPSED: 0.000443464 (sumiter)
ELAPSED: 0.000381538 (sumcall)
ELAPSED: 0.003709807 (sumcia)
BEST: sumcall (4 times)

dotest: N 885387
ELAPSED: 0.002856842 (sumiter)
ELAPSED: 0.002943572 (sumcall)
ELAPSED: 0.022802362 (sumcia)
BEST: sumiter (3 times)

dotest: N 760493
ELAPSED: 0.005853769 (sumiter)
ELAPSED: 0.004284444 (sumcall)
ELAPSED: 0.016364582 (sumcia)
BEST: sumcall (5 times)

dotest: N 516650
ELAPSED: 0.001944555 (sumiter)
ELAPSED: 0.001976967 (sumcall)
ELAPSED: 0.009940383 (sumcia)
BEST: sumiter (4 times)

dotest: N 641422
ELAPSED: 0.002302542 (sumiter)
ELAPSED: 0.002202840 (sumcall)
ELAPSED: 0.011445785 (sumcia)
BEST: sumcall (6 times)

dotest: N 202363
ELAPSED: 0.000285884 (sumiter)
ELAPSED: 0.000311852 (sumcall)
ELAPSED: 0.003159435 (sumcia)
BEST: sumiter (5 times)

dotest: N 490028
ELAPSED: 0.001514360 (sumiter)
ELAPSED: 0.001466043 (sumcall)
ELAPSED: 0.008706644 (sumcia)
BEST: sumcall (7 times)

dotest: N 368691
ELAPSED: 0.001025306 (sumiter)
ELAPSED: 0.000961459 (sumcall)
ELAPSED: 0.006162354 (sumcia)
BEST: sumcall (8 times)

dotest: N 520060
ELAPSED: 0.001497262 (sumiter)
ELAPSED: 0.001586368 (sumcall)
ELAPSED: 0.009255096 (sumcia)
BEST: sumiter (6 times)

dotest: N 897764
ELAPSED: 0.002939831 (sumiter)
ELAPSED: 0.002881219 (sumcall)
ELAPSED: 0.016707118 (sumcia)
BEST: sumcall (9 times)

dotest: N 513927
ELAPSED: 0.001416308 (sumiter)
ELAPSED: 0.001367614 (sumcall)
ELAPSED: 0.009001773 (sumcia)
BEST: sumcall (10 times)

dotest: N 180541
ELAPSED: 0.000243008 (sumiter)
ELAPSED: 0.000239538 (sumcall)
ELAPSED: 0.002559435 (sumcia)
BEST: sumcall (11 times)

dotest: N 383427
ELAPSED: 0.000952569 (sumiter)
ELAPSED: 0.000931755 (sumcall)
ELAPSED: 0.006504057 (sumcia)
BEST: sumcall (12 times)

dotest: N 89173
ELAPSED: 0.000118174 (sumiter)
ELAPSED: 0.000116643 (sumcall)
ELAPSED: 0.000757717 (sumcia)
BEST: sumcall (13 times)

dotest: N 455737
ELAPSED: 0.001378270 (sumiter)
ELAPSED: 0.001315465 (sumcall)
ELAPSED: 0.007850135 (sumcia)
BEST: sumcall (14 times)

dotest: N 5212
ELAPSED: 0.000005663 (sumiter)
ELAPSED: 0.000005643 (sumcall)
ELAPSED: 0.000032479 (sumcia)
BEST: sumcall (15 times)

dotest: N 595369
ELAPSED: 0.001752237 (sumiter)
ELAPSED: 0.001727643 (sumcall)
ELAPSED: 0.010160110 (sumcia)
BEST: sumcall (16 times)

但是,这里是输出-O3

dotest: N 4
ELAPSED: 0.000000061 (sumiter)
ELAPSED: 0.000000058 (sumcall)
ELAPSED: 0.000000077 (sumcia)
BEST: sumcall (1 times)

dotest: N 34
ELAPSED: 0.000000066 (sumiter)
ELAPSED: 0.000000104 (sumcall)
ELAPSED: 0.000000301 (sumcia)
BEST: sumiter (1 times)

dotest: N 692778
ELAPSED: 0.002209531 (sumiter)
ELAPSED: 0.002396807 (sumcall)
ELAPSED: 0.012517166 (sumcia)
BEST: sumiter (2 times)

dotest: N 636916
ELAPSED: 0.001690255 (sumiter)
ELAPSED: 0.001920715 (sumcall)
ELAPSED: 0.011362423 (sumcia)
BEST: sumiter (3 times)

dotest: N 747794
ELAPSED: 0.002070943 (sumiter)
ELAPSED: 0.002294327 (sumcall)
ELAPSED: 0.013792094 (sumcia)
BEST: sumiter (4 times)

dotest: N 238336
ELAPSED: 0.000358729 (sumiter)
ELAPSED: 0.000354468 (sumcall)
ELAPSED: 0.003499538 (sumcia)
BEST: sumcall (2 times)

dotest: N 885387
ELAPSED: 0.004246246 (sumiter)
ELAPSED: 0.004364282 (sumcall)
ELAPSED: 0.024312321 (sumcia)
BEST: sumiter (5 times)

dotest: N 760493
ELAPSED: 0.002452109 (sumiter)
ELAPSED: 0.003049928 (sumcall)
ELAPSED: 0.013849192 (sumcia)
BEST: sumiter (6 times)

dotest: N 516650
ELAPSED: 0.001331265 (sumiter)
ELAPSED: 0.001387272 (sumcall)
ELAPSED: 0.009053577 (sumcia)
BEST: sumiter (7 times)

dotest: N 641422
ELAPSED: 0.001681784 (sumiter)
ELAPSED: 0.001777012 (sumcall)
ELAPSED: 0.011311826 (sumcia)
BEST: sumiter (8 times)

dotest: N 202363
ELAPSED: 0.000244712 (sumiter)
ELAPSED: 0.000315439 (sumcall)
ELAPSED: 0.002864857 (sumcia)
BEST: sumiter (9 times)

dotest: N 490028
ELAPSED: 0.001249077 (sumiter)
ELAPSED: 0.001322027 (sumcall)
ELAPSED: 0.008425179 (sumcia)
BEST: sumiter (10 times)

dotest: N 368691
ELAPSED: 0.001146392 (sumiter)
ELAPSED: 0.000941854 (sumcall)
ELAPSED: 0.005957630 (sumcia)
BEST: sumcall (3 times)

dotest: N 520060
ELAPSED: 0.001347512 (sumiter)
ELAPSED: 0.001452342 (sumcall)
ELAPSED: 0.008846269 (sumcia)
BEST: sumiter (11 times)

dotest: N 897764
ELAPSED: 0.002495836 (sumiter)
ELAPSED: 0.002817348 (sumcall)
ELAPSED: 0.021163486 (sumcia)
BEST: sumiter (12 times)

dotest: N 513927
ELAPSED: 0.003603522 (sumiter)
ELAPSED: 0.003335355 (sumcall)
ELAPSED: 0.010755654 (sumcia)
BEST: sumcall (4 times)

dotest: N 180541
ELAPSED: 0.000270910 (sumiter)
ELAPSED: 0.000308384 (sumcall)
ELAPSED: 0.003348084 (sumcia)
BEST: sumiter (13 times)

dotest: N 383427
ELAPSED: 0.001215342 (sumiter)
ELAPSED: 0.001520112 (sumcall)
ELAPSED: 0.008144502 (sumcia)
BEST: sumiter (14 times)

dotest: N 89173
ELAPSED: 0.000108698 (sumiter)
ELAPSED: 0.000133748 (sumcall)
ELAPSED: 0.000855184 (sumcia)
BEST: sumiter (15 times)

dotest: N 455737
ELAPSED: 0.001418886 (sumiter)
ELAPSED: 0.001442705 (sumcall)
ELAPSED: 0.008022073 (sumcia)
BEST: sumiter (16 times)

dotest: N 5212
ELAPSED: 0.000003999 (sumiter)
ELAPSED: 0.000004181 (sumcall)
ELAPSED: 0.000037246 (sumcia)
BEST: sumiter (17 times)

dotest: N 595369
ELAPSED: 0.001566719 (sumiter)
ELAPSED: 0.001623171 (sumcall)
ELAPSED: 0.010692337 (sumcia)
BEST: sumiter (18 times)

推荐阅读