zoukankan      html  css  js  c++  java
  • APUE 练习题4.11

    题目是:

    4.11 4.21节中的myftw从不改变其目录,对这种处理方法进行改动:每次遇到一个目录就用其调用chdir,这样每次调用lstat时,就可以使用文件名而非绝对文件名,处理完所有目录后再调用chdir(".."),比较这两种的运行时间。


    使用chdir的时间是:1003192 us
    不使用chdir的时间是:time: 2291574 us
    明显是使用了chdir会快一倍

    但是,为什么会快一倍,有人知道合理的解释吗?

    以下是这两个程序的源代码


    ftw8: 使用绝对路径的

    #include "apue.h"
    #include <dirent.h>
    #include <limits.h>
    #include <sys/time.h>
    
    typedef int Myfunc(const char *, const struct stat *, int);
    
    static Myfunc myfunc;
    static int myftw(char *k, Myfunc *);
    static int dopath(Myfunc *);
    
    static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;
    
    
    int main(int argc, char *argv[])
    {
        struct timeval start, end;
        int ret;
        int timeuse;
        if (argc != 2)
            err_quit("usage: ftw <starting-pathname>");
        gettimeofday( &start, NULL );
        ret = myftw(argv[1], myfunc);
    
        ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
    
        if (ntot == 0)
            ntot = 1;
    
        printf("regular files = %7ld, %5.2f %%
    ", nreg, nreg*100.0/ntot);
    
        printf("directories = %7ld, %5.2f %%
    ", ndir, ndir*100.0/ntot);
    
        printf("block special = %7ld, %5.2f %%
    ", nblk, nblk*100.0/ntot);
    
        printf("char special = %7ld, %5.2f %%
    ", nchr, nchr*100.0/ntot);
    
        printf("FIFOs = %7ld, %5.2f %%
    ", nfifo, nfifo*100.0/ntot);
    
        printf("symbolic links = %7ld, %5.2f %%
    ", nslink, nslink*100.0/ntot);
    
        printf("sockets = %7ld, %5.2f %%
    ", nsock, nsock*100.0/ntot);
        gettimeofday( &end, NULL );
        timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec -start.tv_usec;
        printf("time: %d us
    ", timeuse);
        exit(ret);
    }
    
    #define FTW_F 1
    #define FTW_D 2
    #define FTW_DNR 3
    #define FTW_NS 4
    
    static char *fullpath;
    static size_t pathlen;
    static int myftw(char *pathname, Myfunc *func)
    {
        fullpath = path_alloc((&pathlen));
    
        if (pathlen <= strlen(pathname)) {
            pathlen = strlen(pathname) * 2;
            if ((fullpath = realloc(fullpath, pathlen)) == NULL)
                err_sys("realloc failed");
        }
    
        strcpy(fullpath, pathname);
        return(dopath(func));
    }
    
    static int dopath(Myfunc *func)
    {
        struct stat statbuf;
        struct dirent *dirp;
        DIR *dp;
        int ret, n;
    
        if (lstat(fullpath, &statbuf) < 0)
            return(func(fullpath, &statbuf, FTW_NS));
    
        if (S_ISDIR(statbuf.st_mode) == 0)
            return(func(fullpath, &statbuf, FTW_F));
    
        if ((ret = func(fullpath, &statbuf, FTW_D)) != 0)
            return(ret);
    
        n = strlen(fullpath);
    
        if (n + NAME_MAX + 2 > pathlen) {
            pathlen *= 2;
            if ((fullpath = realloc(fullpath, pathlen)) == NULL)
                err_sys("realloc failed");
        }
    
        fullpath[n++] = '/';
        fullpath[n] = 0;
    
        if ((dp = opendir(fullpath)) == NULL)
            return(func(fullpath, &statbuf, FTW_DNR));
    
        while ((dirp = readdir(dp)) != NULL) {
            if (strcmp(dirp->d_name, ".") == 0 ||
                strcmp(dirp->d_name, "..") == 0)
                continue;
    
            strcpy(&fullpath[n], dirp->d_name);
            printf("%s
    ",fullpath);
            if ((ret = dopath(func)) != 0)
                break;
        }
    
        if (closedir(dp) < 0)
            err_ret("can't close directory %s", fullpath);
        return(ret);
    }
    
                   
    static int myfunc(const char *pathname, const struct stat *statptr, int type)
    {
        switch (type) {
        case FTW_F:
            switch (statptr->st_mode & S_IFMT) {
            case S_IFREG: nreg++; break;
            case S_IFBLK: nblk++; break;
            case S_IFCHR: nchr++; break;
            case S_IFIFO: nfifo++; break;
            case S_IFLNK: nslink++; break;
            case S_IFSOCK: nsock++; break;
            case S_IFDIR:
                err_dump("for S_IFDIR for %s", pathname);
            }
            break;
        case FTW_D:
            ndir++;
            break;
        case FTW_DNR:
            err_ret("can't read directory %s", pathname);
        case FTW_NS:
            err_ret("stat error for %s", pathname);
            break;
        default:
            err_dump("unknown type %d for pathname %s", type, pathname);
        }
        return(0);
    }

    e_4_11.c 使用chdir的

    #include "apue.h"
    #include <dirent.h>
    #include <limits.h>
    #include <sys/time.h>
    
    typedef int Myfunc(const char *, const struct stat *, int);
    
    static Myfunc myfunc;
    static int myftw(char *k, Myfunc *);
    static int dopath(Myfunc *);
    
    static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;
    
    
    int main(int argc, char *argv[])
    {
        struct timeval start, end;
        int ret;
        int timeuse;
        if (argc != 2)
            err_quit("usage: ftw <starting-pathname>");
        gettimeofday( &start, NULL );
        ret = myftw(argv[1], myfunc);
    
        ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
    
        if (ntot == 0)
            ntot = 1;
    
        printf("regular files = %7ld, %5.2f %%
    ", nreg, nreg*100.0/ntot);
    
        printf("directories = %7ld, %5.2f %%
    ", ndir, ndir*100.0/ntot);
    
        printf("block special = %7ld, %5.2f %%
    ", nblk, nblk*100.0/ntot);
    
        printf("char special = %7ld, %5.2f %%
    ", nchr, nchr*100.0/ntot);
    
        printf("FIFOs = %7ld, %5.2f %%
    ", nfifo, nfifo*100.0/ntot);
    
        printf("symbolic links = %7ld, %5.2f %%
    ", nslink, nslink*100.0/ntot);
    
        printf("sockets = %7ld, %5.2f %%
    ", nsock, nsock*100.0/ntot);
        gettimeofday( &end, NULL );
        timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec -start.tv_usec;
        printf("time: %d us
    ", timeuse);
        exit(ret);
    }
    
    #define FTW_F 1
    #define FTW_D 2
    #define FTW_DNR 3
    #define FTW_NS 4
    
    static char *fullpath;
    static size_t pathlen;
    static int myftw(char *pathname, Myfunc *func)
    {
        fullpath = path_alloc((&pathlen));
    
        if (pathlen <= strlen(pathname)) {
            pathlen = strlen(pathname) * 2;
            if ((fullpath = realloc(fullpath, pathlen)) == NULL)
                err_sys("realloc failed");
        }
    
        strcpy(fullpath, pathname);
        return(dopath(func));
    }
    
    static int dopath(Myfunc *func)
    {
        struct stat statbuf;
        struct dirent *dirp;
        DIR *dp;
        int ret, n;
        char *tmp;
    
        if (lstat(fullpath, &statbuf) < 0)
            return(func(fullpath, &statbuf, FTW_NS));
    
        if (S_ISDIR(statbuf.st_mode) == 0)
            return(func(fullpath, &statbuf, FTW_F));
    
        if ((ret = func(fullpath, &statbuf, FTW_D)) != 0)
            return(ret);
    
        n = strlen(fullpath);
    
        if (n + NAME_MAX + 2 > pathlen) {
            pathlen *= 2;
            if ((fullpath = realloc(fullpath, pathlen)) == NULL)
                err_sys("realloc failed");
        }
    
        fullpath[n++] = '/';
        fullpath[n] = 0;
    
        if (chdir(fullpath) < 0) 
            err_quit("chdir error");
    
        if ((dp = opendir(".")) == NULL)
            return(func(fullpath, &statbuf, FTW_DNR));
    
        while ((dirp = readdir(dp)) != NULL) {
            if (strcmp(dirp->d_name, ".") == 0 ||
                strcmp(dirp->d_name, "..") == 0)
                continue;
            
            
            strcpy(&fullpath[n], dirp->d_name);
            if ((tmp = (char *)malloc(strlen(fullpath)+1)) == NULL)
                err_quit("malloc error");
            strcpy(tmp, fullpath);
            strcpy(fullpath, dirp->d_name);
            printf("%s
    ",fullpath);
            if ((ret = dopath(func)) != 0)
                break;
        }
    
        if (closedir(dp) < 0)
            err_ret("can't close directory %s", fullpath);
    
        if (chdir("..") < 0) 
            err_quit("chdir to .. error");
        return(ret);
    }
    
    
                   
    static int myfunc(const char *pathname, const struct stat *statptr, int type)
    {
        switch (type) {
        case FTW_F:
            switch (statptr->st_mode & S_IFMT) {
            case S_IFREG: nreg++; break;
            case S_IFBLK: nblk++; break;
            case S_IFCHR: nchr++; break;
            case S_IFIFO: nfifo++; break;
            case S_IFLNK: nslink++; break;
            case S_IFSOCK: nsock++; break;
            case S_IFDIR:
                err_dump("for S_IFDIR for %s", pathname);
            }
            break;
        case FTW_D:
            ndir++;
            break;
        case FTW_DNR:
            err_ret("can't read directory %s", pathname);
        case FTW_NS:
            err_ret("stat error for %s", pathname);
            break;
        default:
            err_dump("unknown type %d for pathname %s", type, pathname);
        }
        return(0);
    }
  • 相关阅读:
    netty入门
    zookeeper安装
    nginx
    链式调用方法的实现原理和方法
    UI设计篇·入门篇·简单动画的实现,为布局设置动画,用XML布置布局动画
    UI设计篇·入门篇·简单动画的实现,透明动画/旋转动画/移动动画/缩放动画,混合动画效果的实现,为动画设置监听事件,自定义动画的方法
    UI设计篇·入门篇·绘制简单自定义矩形图/设置按钮按下弹起颜色变化/设置图形旋转
    XML文档的生成和解析操作方法
    ListView的基本使用方法和RecyclerView的基本使用方法
    Fragment的粗浅理解
  • 原文地址:https://www.cnblogs.com/hwy89289709/p/6944969.html
Copyright © 2011-2022 走看看