Posted on 2008-05-21 11:45
dennis 阅读(1936)
评论(4) 编辑 收藏 所属分类:
动态语言 、
涂鸦 、
计算机科学与基础
转眼间,来广州快半年了,感觉还不错。广州如死鱼所说的那样,是个包容并且很有活力的城市,习惯了周末煲汤,去天河公园跑跑步,这生活还是挺舒适的,除了比较潮的天气。
最近跟公司闹了点不愉快,在转正时间上,其实不是多大的事,只是心里不舒服罢了,干起活来也没什么激情了,呵呵。当然,手头的工作咱还是要高效率地完成,做完两个游戏后,现在转到棋牌类,棋牌类游戏核心就两个算法:随机发牌和出牌判断。随机发牌算法,学习了云风的blog上提到的方法,感觉还可以接受;出牌规则判断,倒是没想象中的复杂,建立牌型的OO模型,一切都很简单了。另外一个发现,用jdk6跑jruby1.1.1,比用jdk5跑效率(包括内存和CPU)好上很多,例如我们一个游戏进程,在使用jdk5时,CPU稳定在15%,内存85M,而改用jdk6后,cpu降到了%5以下,内存也缩减到70多M。
搞完了之后,时间有点空闲,就想学点新东西,最后选择了Prolog。Yep,非常地有趣,真正的声明式编程语言。Prolog本质上就是两个东西:规则和事实,由事实和规则出发,Prolog的推理系统将回答你的查询(query)。有点类似现在流行中的规则引擎的概念,在对效率不是很考虑的场景中,嵌入一个Prolog引擎做规则引擎完全是可以的,java中有个tuProlog项目,可以关注一下。然后就是一直在读的sicp,延时求值模拟无穷级数实在是相当地cool,大开眼界。这两天一直在理解continuation这个概念,小有所得。一个表达式的求值可以分为两个阶段:“What to evaluate?”和“What to do with the value”,“What to do with the value”就是计算的Continuation。例如,scheme求值下列表达式:
(if (null? x) (quote ()) (cdr x))
先求值表达式(null? x),(null? x)就是“What to evaluate”,当(null? x)求值后,需要根据这个值来决定是执行(quote ())还是(cdr x),这个根据值来决定的过程就是Continuation。如果在每次函数调用时,同时传入当前的continuation,那么就完全可以不要堆栈。call/cc就提供了这样的一个语法糖,call/cc全称就是call-with-current-continuation,要求参数是一个过程,调用这个过程,并且向这个过程传入当前的continuation(一般称为k,kont,或者Ruby中一般是c,cont),这就是call/cc为我们做的。call/cc是实现Continuation的方式之一,coroutine/fiber/yield也是实现continuation的方式。《The Scheme Programming Language》给出的轻量级进程机制的例子比较有趣:
(define lwp-list '())
(define (lwp thunk)
(set! lwp-list (append lwp-list (list thunk))))
(define start
(lambda()
(let ((p (car lwp-list)))
(set! lwp-list (cdr lwp-list))
(p))))
(define pause
(lambda()
(callcc (lambda(k)
(lwp (lambda () (k #f)))
(start)))))
(lwp (lambda () (let f () (display "h") (pause) (f))))
(lwp (lambda () (let f () (display "e") (pause) (f))))
(lwp (lambda () (let f () (display "y") (pause) (f))))
(lwp (lambda () (let f () (display "!") (pause) (f))))
(lwp (lambda () (let f () (newline) (pause) (f))))
(start)
实现了代码级的进程调度。