博文

目前显示的是 四月, 2006的博文

getpid

ml:let _ = print_int (Unix.getpid ()); c++:#include <sys/types.h>#include <unistd.h>#include <iostream>intmain(){ pid_t pid=getpid(); std::cout<<"Current Pid:"<<pid<<std::endl; return0; }

奇怪的getc

今天特奇怪,为什么getc总是返回1呢?while( (c=getc(stdin) !=EOF)){ if (putc(c,stdout) ==EOF) perror("output error\n"); } 用gdb调试了很久都不明白
后来才突然发现,括号的顺序写错了while( (c=getc(stdin)) !=EOF){ if (putc(c,stdout) ==EOF) perror("output error\n"); } just fine.

让w3m退出时不用确认

w3m/w3mman按q可以退出,但是要确认,很麻烦。 后来查文档说按大写的Q就不用确认了 但是我闲麻烦 我找w3m的配置,发现它不像w3一样有一个配置界面,也找不到配置文件。 原来... 原来是把默认的key map copy到自己的~/.w3m目录下,然后修改下,把q对应的QUIT修改为EXIT就好了…… 天哪,这是我见过的最奇怪的option

apue实验(二):cat 标准输入与输出

c++ 版:#if HAVE_CONFIG_H# include <config.h>#endif#include <sys/types.h>#include <sys/uio.h>#include <unistd.h>#include <iostream>intmain(void){ int n; const size_t buffersize= 10240; char buf[buffersize]; while( (n=read(STDIN_FILENO,buf,buffersize))>0) { if(write(STDOUT_FILENO,buf,n) !=n) std::cerr<<"write error\n"<<std::endl; } if(n<0) std::cerr<<"read error"<<std::endl; return0; } ocaml 版:letrec mainloop buf buffersize= beginmatchUnix.read Unix.stdin buf 0 buffersize; with0 -> (); | n when n>0 -> beginmatchUnix.write Unix.stdout buf 0 n; with l when l=n -> mainloop buf buffersize; | _ -> Printf.printf "write error\n"; end | n when n<0 -> Printf.printf "read error\n"; endlet _= let buffersize=10240inlet buf=String.create buffersize in mainloop buf buffersize; 我好像用match用的太过分了……
本来应该用if...else...的,在functional programming中用if..…

apue实验(一):dir 目录遍历

C++的#if HAVE_CONFIG_H# include <config.h>#endif#include <sys/types.h>#include <dirent.h>#include <iostream>intmain(int argc,char* argv[]){ //setlocale(LC_ALL,"");if(argc != 2){ std::cerr<<"Wrong number of arguments! Need one"<<std::endl; return -1; } constchar* dirname=argv[1]; DIR* dp=opendir(dirname); if(dp==NULL){ std::cerr<<"error when 'opendir' "<<dirname<<std::endl; return -1; } else{ dirent* dirp; while(( dirp=readdir(dp)) !=NULL) std::cout<<dirp->d_name<<"\n"; closedir(dp); } return0; } ocaml 的letrec next_file dir_handle= try print_string (Unix.readdir dir_handle); print_newline(); next_file dir_handle withEnd_of_file -> (); | Unix.Unix_error(errno,function_name,function_parameter)-> print_string (Unix.error_message errno ) ; print_newline(); | _ -> Pr…

ocaml中这两个modules的区别是什么?

Module "Unix": Unix system callsModule "UnixLabels": Labeled Unix system calls

ocaml里面的fork

let fork_parent()= Printf.printf("Hi,this the parent\n"); tryUnix.wait();(); withUnix.Unix_error(errno,function_name,function_parameter)-> print_string (Unix.error_message errno ) ; print_newline(); | _ -> Printf.printf "Unknown Error"; ();; let fork_child()= Printf.printf "Hi,this the child\n";; let myfork = function0 -> fork_child() | _ -> fork_parent();; let _ = myfork(Unix.fork()); exit 0

关于ocaml性能的测试(三)

这个是改进后的递归求fibonacci数列第n项的算法let fib_next = function(* x->[|x.(1);x.(0)+x.(1)|];; *) [|a;b|]->[|b;a+b|] | _->raise( Invalid_argument"fib_next");; letrec fib= function1->[|0;1|] | n->fib_next( fib (n-1) );; let _= Printf.printf "%d\n" (fib 44).(1); exit 0测试就不必了,因为一闪而过,所花时间的数量级太低,无法比较。
所以说,只要编译器做好优化,用单层递归写的程序,和用单层循环写的程序,效率相差不是很大。

关于ocaml性能的测试(二)

今天经code17提出,我才明白ocamlc编译后所得到的只不过是bytecode。效率当然
没有办法和C比
重新用ocamlopt编译后
并加大计算量,计算第44项,所得统计如下
FreeBSD6.0,AlthonXP 2400+
$ time ./fibc
701408733
17.531u 0.000s 0:17.55 99.8% 5+175k 0+0io 0pf+0w
$ time ./fib
701408733
11.929u 0.000s 0:11.94 99.8% 138+799k 0+0io 0pf+0w
2 * Xeox 3.04G,SMP
$ time ./fib
701408733
11.303u 0.000s 0:11.30 100.0% 128+768k 0+0io 0pf+0w
$ time ./fibc
701408733
16.663u 0.000s 0:16.66 100.0% 5+169k 0+0io 0pf+0w
可见,ocaml所花的时间大概是C的68%左右。
这点让人大大的吃惊。
(我见过唯一在效率上能打败C的就是在科学计算领域的fortran)
我想可能是因为ocaml本身做的最多的运算就是递归,所以编译器在代码生成时对
此做了特殊的优化。
另外想问一下,ocaml可不可以当作脚本来用,来代替csh/sh.
今天我刚刚开始学csh script,是在读usd( "UNIX User's Supplementary
Documents (USD) 4.4 Berkeley Software Distribution")。真可惜这么好的文档
为什么我现在才找到……

关于ocaml性能的测试(一)

(特注:这是一篇很无知的日记,我留着它只是为了记录我当初做了什么,而不是为了告诉别人什么)今天用写了个计算Fibonacci数列的程序,顺便和C/C++比较一下效率。
要求:计算Fibonacci数列第38项是多少递归的ocaml的letrec fib = function0 ->; 0 | 1 ->; 1 | n ->; fib (n-2) + fib (n-1);; let main () = Printf.printf "%d" (fib 38); print_newline(); exit 0;; main();; 这个是递归的C的,编译为fibc#include <stdio.h>;intfib(int n){ return n==0?0: n==1?1: fib(n-1)+fib(n-2); } intmain(){ int n=38; printf("%d\n",fib(n)); return0; } 非递归的C++的,编译为fibc2#include <iostream>;#include <algorithm>;intmain(){ constintn(38); inta(1),b(1); for(int i=2;i!=38;i++){ a+=b; std::swap(a,b); } std::cout<<b<<std::endl; return0; } 编译时都加了-g选项加入了调试符号,没有加-O优化第一个测试环境所用C/C++编译器为gcc (GCC) 3.4.4 [FreeBSD] 20050518
所用ocaml编译器为ocamlc 3.09.0
操作系统为FreeBSD 6.0p6
单CPU,AlthonXP 2400+
这个是运行结果
$ time ./fib
39088169
10.905u 0.000s 0:10.91 99.9% 154+921k 0+0io 0pf+0w$ time ./fibc
39088169
0.950u 0.000s 0:00.95 100.0% 5+176k 0+0io 0pf+0w$ time ./fibc2
39088169
0.00…

locale

今天本来是切到FreeBSD下来写程序的,没想到在smth的FreeBSD版和他们争论起locale来,学到不少知识。今天下了berkeley DB XML,不知道啥是嵌入式数据库,难道access这样的就算?
刚开始一切顺利,就是写了很多很多try...catch... 而已。后来,在createContainer的时候出错了,总是throw bad_alloc。 这个一般是在内存不足的时候throw的。准确来说,new失败了。 这样的情况我很少见。调试了N次,怎么修改代码都不行。本来samples里面的代码还是可以运行的。我似乎运行过一次。后来连sample里面的代码都 throw这个。OMG~google里面搜到一篇帖子,其实是在新闻组上。我没看懂,大概是说,按照文档重新编译一次就好了。"compile every per document"我不知道是啥意思。嗯,估计和我一样,操着半生不熟的英语混迹在新闻组中询问莫名奇妙的bug。不过我很没有耐心,我不想再重新编译一 次Berkeley DB了,是的,我装的是预编译版,多轻松啦,尽管很不好。它用的是vc71而我是vc80.但是如果我重新编译这个还需要tcl等等的头文件,那我才郁闷 呢,不干不干……我突然感叹,还是FreeBSD好,装啥都方便。 结果……结果……嗯,也有不方便的时候,这个居然依赖于JDK1.3.2,我讨厌死java了,但是上次还是耐着性子装了JDK1.5的binary包,准确来说,赶新 潮。可是呢……它要的是JDK1.3.2而不是JDK1.5。好吧,重新从网上下载JDK的源代码,下patchs,郁闷……还好,轻车熟路,很快就结束 了。中间接了Alyarce的一个电话,还听陈柳介绍了下男人必看的10部动画片。可惜啊,我就喜欢篮球飞人和幽幽白书。Berkeley DB是我用过的第一个不支持SQL的database.好奇……我还不会XPath/XQuery,嗯,还需要些时间来学习这些新东西。还好,明天还是无事可作,哈哈发现,要在gcc下用wprintf输出中文,那么必须把源代码用utf8保存,然后把locale设置为zh_CN.UTF-8这样的,才可以……为啥 必须要用unicode呢……我可怜的emacs啊……just so~

CPUID,用于显示CPU的vendor information

.section.dataoutput:.asciz"The processor Vendor ID is '%s'\n".section.bss.lcomm buffer ,24.section.text.globl main main: #eax里面存放的是cpuid这个指令的参数 #eax=0时输出processor Vendor information movl $0,%eaxcpuid movl $buffer,%edi # EBX contains the low 4 bytes of the string. # EDX contains the middle 4 bytes of the string. # ECX contains the last 4 bytes of the string. # 把他们放在一起 movl %ebx,(%edi) movl %edx,4(%edi) movl %ecx,8(%edi) #用printf输出 pushl $buffer pushl $output call printf addl $8,%esp #程序结束,调用exit并退出 pushl $0call exit