Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
181 views
in Technique[技术] by (71.8m points)

c - Why evaluating sizeof in a loop isn't faster than using a fixed number for the size of the object?

When it comes to writing & reading data (variables and objects) from & to files, our teacher told us to do it like this:

while(1){
if(fwrite(&object, sizeof object, 1, fp)!= 1){
break;
}

However, it seems rather logical that this should be faster:

int num = sizeof object;
while(1){
if(fwrite(&object, num, 1, fp)!=1){
break;
}

After all, evaluating the size of the object won't be done every iteration. So, I wrote a simple program to test this:

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

struct block{
    int val;
    float mal; //the variables are irrelevant here
    char *ch;
}object;

int main(void){
    FILE *fp;

     int f = sizeof object;

    if((fp=fopen("file.bin", "wb"))==NULL){
        puts("Unable to open file.");
        exit(1);
    }
    int n = 2; //either set n to 1 or 2 
    switch(n){
        case 1: 
        for(int i = 0; i <101; i++){
        if(fwrite(&object, sizeof object, 1, fp)!=1){
            puts("I/O error.");
            break;
        }
        break;
    }
    case 2: 
    for(int i = 0; i <101; i++){
        if(fwrite(&object, f, 1, fp)!=1){
            puts("I/O error.");
            break;
}
break;
}
}
puts("Fin.");
    return 0;
}

However, when I ran this program multiple times in devc++, to my surprise there was basically no difference in time passed. For n = 1 I got these times: 0.0292, 0.02757, 0.02946, 0.02847. For n = 2: 0.03022, 0.028, 0.02954, 0.02885. The second option isn't faster and there appears to be no distinguishable pattern. What gives?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you inspect the intermediate compilation results, you can see how they're essentially equivalent.

Compiling using gcc and the -fdump-tree-optimized flag produces the following results:

$ ls
speedtest.c
$ gcc -fdump-tree-optimized speedtest.c
$ ls
a.out  speedtest.c  speedtest.c.227t.optimized

If you take a peek in the *.optimized file, you'll find excerpts like:

For int f = sizeof object;:

f_9 = 16;

For fwrite(&object, sizeof object, 1, fp):

_1 = fwrite (&object, 16, 1, fp_12);

For fwrite(&object, sizeof object, 1, fp), which is utilizing the assignment in the first excerpt:

_2 = (long unsigned int) f_9;
_3 = fwrite (&object, _2, 1, fp_12);

As you can see, the sizeof operator is being evaluated at compile time.

The sizeof operator is a documented part of the C standard and is defined alongside other unary operators, such as ++ and --.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...