سؤال

Why is buffered 0.030000 seconds the same as "better" buffered 0.030000 seconds ? If 4 times larger linesize won't change time, how can I speed it up even more?

Test

$ ./a.out 
Unbuffered: 0.770000 seconds
Buffered: 0.030000 seconds
Better buffered: 0.030000 seconds

Code

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 1024 /* read 1024 bytes at a time */
#define betterSIZE 4096 /* read a better size at a time */

int copy() /* input2output ie anything to anything */
{
    char buf[betterSIZE];
    int n;
    while ((n = read(0, buf, betterSIZE)) > 0)
    write(1, buf, n);
    return 0;
}

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

    /* copy(); */

    /* make the names known */

    void info(char file_name[]);
    void buffered(char file_name[]);
    void better_buffered(char file_name[]);

   /* test */

    clock_t toc;
    clock_t tic = clock();
    info("coreutils_8.13.orig.tar.gz"); 
    info("coreutils_8.13.orig.tar.gz"); 
    info("coreutils_8.13.orig.tar.gz"); 
    info("coreutils_8.13.orig.tar.gz"); 
    info("coreutils_8.13.orig.tar.gz"); 
    toc = clock();
    printf("Unbuffered: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);
    tic = clock();    
    buffered("coreutils_8.13.orig.tar.gz"); 
    buffered("coreutils_8.13.orig.tar.gz"); 
    buffered("coreutils_8.13.orig.tar.gz"); 
    buffered("coreutils_8.13.orig.tar.gz");
    buffered("coreutils_8.13.orig.tar.gz"); 
    toc = clock();
    printf("Buffered: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);
    tic = clock();    
    better_buffered("coreutils_8.13.orig.tar.gz"); 
    better_buffered("coreutils_8.13.orig.tar.gz"); 
    better_buffered("coreutils_8.13.orig.tar.gz"); 
    better_buffered("coreutils_8.13.orig.tar.gz");
    better_buffered("coreutils_8.13.orig.tar.gz"); 
    toc = clock();
    printf("Better buffered: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);
    return 0;
}

void info(char file_name[])
{
    int ch;
    FILE *fp;
    fp = fopen(file_name,"r");
    // read mode
    if (fp == NULL)
    {
        perror(file_name);
        exit(EXIT_FAILURE);
    }
    while ((ch = fgetc(fp)) != EOF)
    {
        //putchar(ch);
    }
    fclose(fp);
}

void buffered(char file_name[])
{
    char buf[SIZE];
    FILE *fp;
    size_t nread;
    fp = fopen(file_name, "r");
    if (fp) {
        while ((nread = fread(buf, 1, sizeof buf, fp)) > 0)
    {
            //fwrite(buf, 1, nread, stdout);
    }
        if (ferror(fp)) {
            /* to do: deal with error */
        }
        fclose(fp);
    }
}


void better_buffered(char file_name[])
{
    char buf[betterSIZE];
    FILE *fp;
    size_t nread;
    fp = fopen(file_name, "r");
    if (fp) {
        while ((nread = fread(buf, 1, sizeof buf, fp)) > 0)
    {
            //fwrite(buf, 1, nread, stdout);
    }
        if (ferror(fp)) {
            /* to do: deal with error */
        }
        fclose(fp);
    }
}
هل كانت مفيدة؟

المحلول

fread already buffers data, i.e. internally reads it in chunks typically 4K or 8K in size (the exact default buffer size is defined by the implementation). For this reason, switching your reads from 1K to 4K does nothing, as it only decreases the number of memcpy operations, which are cheap enough not to register in the benchmark above statistical noise.

To influence the size of the stdio buffer, take a look at setbuf.

Also, what you are changing is not line size because you're not reading the file line by line, but chunk size.

نصائح أخرى

The OS will read whole blocks/sectors from the HD anyway, enough to fill a page, and then caches that for a while.
So it doesn't matter if you read 1024 or 4096. A page is usually 4096.

If you want to speed it up, try reading a few pages together. 8 Pages for example.

#define PAGE_SIZE 4096
#define betterSIZE 8*PAGE_SIZE 

The stdio library implements a buffer in itself - so the two functions are essentially the same as both with use the same size buffer as implemented by the library.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top