打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
人人网

动态语言编译器之辩 作者: 王超

又是快一个月没有更新了,呵呵呵(挠头中…)。最近一直在搞PHP的那个server(其实是在天天party吧魂淡!+_+),首先从IOStream入手。现在已经有了一个简单的实现,等全部做好了再来发一篇帖子。言归正传,这篇博客主要想讨论一个问题,就是现在越来越热闹的“动态语言编译器”。

所谓“动态语言编译器”,顾名思义,就是把动态类型语言,尤其是PHP, Python等编译成静态代码如C再执行的工具。随着Web开发的不断流行和深入,动态语言的使用面也越来越广,而动辄100M日访问量的强大压力也对语言的执行效率提出了新的要求。由此“动态语言编译器”应运而生。它们当中的杰出代表当属HIPHOP (Facebook开发的PHP-C编译器),以及Shed-skin (Python-C编译器)。

开宗明义——我对动态语言编译器的两个观点:

  1. 动态语言中的动态特性要慎用。
  2. (或许) 动态语言编译器只是“在错误的地点解决了一个错误的问题”。

动态语言中的动态特性要慎用

这是我一直以来都强调的一点。动态特性在给予我们编程方便的同时,也带来了代码结构性降低、可维护性差等诸多缺点。近来的开发工作令我越来越发现,相对于驾驭静态语言而言,使用动态语言开发对于程序员的能力和自律性要求更高。这一点对于1M日访问量以下的网站是微不足道的,但是对于20M以上的网站而言却不可不防。事实上像Facebook/Zynga这样的大型公司都在PHP上面吃了不少苦头,而Facebook更是毅然重写了绝大部分代码并做到全站编译化,以杜绝PHP的流弊。

因此,我建议将“可用的动态性”仅仅限于以下的几个方面:

  • 反射机制,以解决类构造、串行化(serialization) 的问题。
  • 函数分派机制,以解决按函数名调用的问题。
  • 闭包,主要解决异步执行的问题。
  • 类型推导和范型化容器。
  • 有限的类动态扩展,以避免反复定义大致类似但小有不同的类。

有趣的是,现代静态语言都不谋而合地已经或正在实现以上的几点。Java是这方面的先行者,基本实现了以上的大部分特性(反射、范型、匿名类)并正在实现其他的功能(JSR 335: Lambda Expressions);而就连以保守(性能优先)而著称的C++,也在新版本11中包括了以binding/lambda为特点的新功能。从这个意义上来说,静态语言也已经动态化了。

另一方面,那些“坏的”动态性则应当在编程中予以避免。比如“多类型赋值”,即将无继承关系的类型,如数字类型、字符串型赋值到同一个变量上;又或者是臭名昭著的“eval”,在程序执行过程中动态生成新的程序(Geek很喜欢这个。程序生成程序、人工智能、想想都很酷。),等等。这些除了能显得这段程序与众不同并为开发思维带来混乱以外,不会带来任何实质性的好处。

(或许) 动态语言编译器只是“在错误的地点解决了一个错误的问题”

事实上我对于动态语言编译器的认识也经历了一个从完全赞同到持保留态度的过程。至于相关的编译器们,如PHP的Java版Quercus、C++版HIPHOP;Python的Unladen-Swallow、Shed-skin、pypy,我都曾经或多或少地使用或试用过。它们在执行性能方面的改进都是令人赞赏的。但是也普遍有以下的问题:

  • 语言本体受限:这些编译器往往都只覆盖了原语言的一部分功能集合。
  • 库扩展受限:库已经成为现代编程语言所不可或缺的一部分,而囿于语言本身的实现情况,很多库在编译器上并不能正常工作。
  • 没有得到广泛充分的实践检验:除了HIPHOP,大部分的编译器都是处于试验阶段,因此bug、issue在所难免。将之贸然应用到生产环境中将存在很大的风险。
  • 社区支持有限:“编译动态语言”本来就是一件小众的事情,因此获得较少的外部支持也就理所应当了。就连编译器本身的进展也是一个问题。例如截至本文发表之日止,HIPHOP尚不支持PHP 5.3,Unladen-Swallow计划已经终止,等等。而另一方面,这些小众社区的理念又不能很好地反馈回主流社区,所以无法对语言的演进产生影响。

如果我们深入地想一下,这些编译器解决了什么问题呢?它们事实上是将动态语言变成了静态语言的一种“方言”,即用动态语言的语法来写静态语言的程序。理解了这一点,也就可以理解主流动态语言社区对于这种类型的工作并不感冒的原因了。

该怎么办?

上面的内容讨论的主要是“问题”。下面来谈谈我心中的解决方案:

  • 用改进后的静态语言代替动态语言。Java,尤其是轻量级的Java(与动辄架构、模型的重量级结构相区分),是一种可靠的前端(Front-end)开发语言,可以做到能力和效率之间的平衡。推荐。关于架构,这里多说一句。在我看来所谓的web服务器无非就是解决好如下4件事情。我对现在很多的重量级架构是深恶痛绝,那简直就是叠床架屋无效率的典范。
    1. 响应请求:是否能做到异步?是否能做到multiplexing?
    2. 路径映射:这是个部署问题。
    3. 分层处理:从逻辑上以Filter解决不同层次的需求。
    4. 内容渲染:一个好的模板系统。这最后一条一般是与具体服务器的选择分开的。比如在Python服务器中,如果选择了Tornado作为web服务器,则模板系统可以选用用django,也可以是jinja2或其他。现在网上很多的讨论根本就是Apple v.s Orange.
  • 效率之源在于实现而不是语言本身。动态语言的应用场景多见于Web服务器和前端,尤其是利用Apache+CGI作为基本架构。而事实上这才是效率低下的原因之一。以PHP为例,Apache+CGI < Apache+FPM < Nginx + FPM。而Python则最好使用Tornado。再比如,PHP也可以支持Socket server。囿于开发人员的(平均)水平,很多时候动态语言的实现往往要劣于它们静态语言的参照物。因此立足于本体,改进实现,这才是一条稳健的道路。
  • 如果是性能关键应用,使用广受应用的编译器实现。HIPHOP是一个好例子。Facebook有超过10K台服务器在使用这一实现,并且它也做到了相对稳定可靠,并将CPU内存等资源利用率提高了一倍至三倍。因此如果是HIPHOP,这个方案还是可以接受的。

总而言之,具体问题具体分析。在应用某个解决方案之前,一定要对它的优缺点有详尽的了解和分析。

以上是得悉http://code.google.com/p/shedskin/发布新版本后的一点感想。


来源:王超
|分享(5)|浏览(111)
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
动态语言和静态语言的比较
PHP小白必知: web服务器该选择apache还是nginx? 一、apache与nginx的区别: 1、二者最核心的区别在于apache是同步多进程模型,一个连接对应一个进程
Apache 和 Tomcat 整合的好处和意义
Lighttpd Squid Apache搭建高效率Web服务器
nginx做为反向代理实现负载均衡的例子
apache的静态/动态编译在apache+php+mysql的应用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服