文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>从统计代码行数说开

从统计代码行数说开

时间:2010-06-29  来源:xiaosuo

闲得蛋疼,想去统计一下FreeBSD和Linux内核代码行数,好“羞辱”一下FreeBSD,并籍此慰藉一下自己作为Linux用户的虚荣之心(就是鲁迅笔下的阿Q精神):

xiaosuo@gentux FreeBSD $ svn up
版本 209583。
xiaosuo@gentux FreeBSD $ find . -name "*.[hc]" | xargs wc -l
...
  836324 总用量
...
localhost linux # git pull
Already up-to-date.
localhost linux # find . -name "*.[hc]" | xargs wc -l
 19537 total

结果让我愕然,太假了吧,FreeBSD竟然比Linux代码量大,并且Linux才那么点儿代码?应该是统计方法有问题,换用perl语言实现一个统计程序如下:

#!/usr/bin/perl -w
#

$line = 0;


open($files, 'find . -name "*.[hc]" |');
while (<$files>) {
        open($fp, $_);
        while (<$fp>) {
                $line++;
        }
}

print $line . "\n";


运行之:

xiaosuo@gentux FreeBSD $ ./line.pl
3956986
...
localhost linux # ./line.pl
11898857

长出一口气,终于得到了靠谱的数据,并且虚荣心得到些许满足,Linux代码行数是FreeBSD的3倍多。

那么,先前的统计为什么出错了呢?以前我可都是这么统计代码行数的。猜测是因为文件数量太多,xargs不能一次性将所有文件的路径以参数的形式传递给wc,致使wc被调用了多次。检测方法比较简单,在原有的命令基础上再加一个过滤器,筛选出总用量统计。

xiaosuo@gentux FreeBSD $ find . -name "*.[hc]" | xargs wc -l | grep 总用量
 3120662 总用量
  836324 总用量

和结论相符,那么修正一下shell脚本,让xargs每次传给wc一个参数,并用其他方式统计行数。

xiaosuo@gentux FreeBSD $ find . -name "*.[hc]" | xargs -L 1 wc -l | awk '{print $1}' | while read num; do total=$((total+num)); echo $total; done
...
3956986

这次得出了正确的数字,只是速度较慢,其实可以将统计方法应用于上一个过滤后的结果以加速执行。

那么xargs传递的参数个数的上限是多少呢?统计了一下每次wc调用的参数个数:

localhost linux # find . -name "*.[hc]" | xargs ./a.pl
4708
3460
3730
3998
4110
3544
4157
1798

并没有发现任何规律。看来还得翻源码:


/* IEEE Std 1003.1, 2003 specifies that the combined argument and
       * environment list shall not exceed {ARG_MAX}-2048 bytes. It also
       * specifies that it shall be at least LINE_MAX.
       */
#ifdef _SC_ARG_MAX
      long val = sysconf(_SC_ARG_MAX);
      if (val > 0)
        {
          /* Note that val can in fact be greater than ARG_MAX
           * and bc_ctl.arg_max can also be greater than ARG_MAX.
           */
          assert (bc_ctl.arg_max <= (val-XARGS_POSIX_HEADROOM));
        }
      else
        {
# if defined ARG_MAX
          assert (bc_ctl.arg_max <= (ARG_MAX-XARGS_POSIX_HEADROOM));
# endif
        }
#else
      /* No _SC_ARG_MAX */
      assert (bc_ctl.arg_max <= (ARG_MAX-XARGS_POSIX_HEADROOM));
#endif


可见有相关的sysconf变量,但是你查看其相应的man page字段,发现这个数值其实不怎么可靠。

       ARG_MAX - _SC_ARG_MAX
              The  maximum  length  of  the arguments to the exec(3) family of
              functions.  Must not be less than _POSIX_ARG_MAX (4096).

BUGS
       It  is difficult to use ARG_MAX because it is not specified how much of
       the argument space for exec(3) is consumed by  the  user's  environment
       variables.

       Some  returned values may be huge; they are not suitable for allocating
       memory.

比较保险的做法还是尽量避免过多参数吧。
相关阅读 更多 +
排行榜 更多 +
战地方块战场中文版下载

战地方块战场中文版下载

飞行射击 下载
云原神国际服手机版下载

云原神国际服手机版下载

角色扮演 下载
海之号角柯罗诺斯地下城手机版下载

海之号角柯罗诺斯地下城手机版下载

角色扮演 下载