动态语言会淘汰静态语言吗?

上一篇博客动态语言会导致开发质量下降吗?,尽管没有我想像的那么多争议,但还是如期引发了一些误解。有一些朋友指出动态语言,具体来说是 Python 中的各种问题。这些我认为是大部分是正确的。

我写上文的用意,在于讨论动态语言使用过程中,关于质量控制的必要性,以及其引发的性价比方面的争议。这并不表示动态语言全面的优于静态语言,更不表示静态语言会被动态语言全面的取代。进一步,这里我简单的说一下,我所认识到的,静态语言相对的优越性,和存在意义。

这里首先我表达一下我一贯的观点:计算机不会魔法。具体来说两方面,一是离机器越近,性能上越有可能达到更快;二是目前的机器模型,总是以线性方式管理数据的(值得吐槽的是在操作系统以上,文件分区系统也总是这样干的,更底层能否以哪怕是极座标方式,直接在二/三维空间上定位访问,而非扇区、柱面、簇这种形式,我不清楚,有待方家指点)。

线性管理信息带来的效应就是:基于线性数据结构,或以地址访问信息的编程工具,通常来说会比基于字典结构的更快,至少有更大的优化空间。而静态语言的话,编译时我们已经确定了对象的结构和尺寸(动态尺寸的内容可以通过引用管理),这是动态语言无法做到的。动态语言的对象结构,总是基于字典结构,要兼顾对象结构在运行时发生改变的问题。这使得它的数据管理总是要比直接地址访问要多上那么一层。这也是甚少见到动态语言编译器的原因。流行的动态语言,几乎都是解释/字节码平台,甚至,最常见的 Python/Ruby 等等语言,几乎都有饱受批评的 GIL(Global Interpreter Lock)。以 Python 社区的经验来说,多年来出现的数个无GIL的 C-Python 实现,单核性能都不如现在的官方版本。Jython 和 IronPython 则是得益于 JVM 和 CLR,这两个久经经考验的虚拟机平台,它们的 first-class language 都是静态编译型语言(尽管其主流编译器生成的是字节码,但是通常我们都视Java 和 C#为编译语言)。为 Perl 社区期待多年的 Perl6 ,至今还没有真正的发布(其虚拟机 Parrot 虽然已经发布,但受制于主力语言实现进度,现在还没有得到足够的实战验证)。为动态语言实现一个高性能的,特别是并行的高性能环境,难度之高,可见一斑。

根本上说,在当前的硬件模型上,想要以非线性的方式管理信息,动态伸缩,动态修改结构,非常的不容易。举一个例子,候捷老师有一个讲座,是以windows 95为例,詳細讲解 malloc/free 的底层实现,有听过的朋友应该对操作系统动态管理内存资源的复杂程度有所体会。类似的内容在很多操作系统之类的技术书籍中都有介绍,有兴趣的朋友可以找来看看,我手边有一本《Unix系统编程》就有相关的内容。

这类问题涉及比较深入的底层问题,我不是科班出身,这方面比较外行,讲的不是很好,不过有兴趣的朋友可以深究一下,会发现这事儿比看起来要麻烦得多。想要让动态语言达到静态化的性能,是件相当有挑战的事。Google的 Protocol Buffer 协议,也是基于静态模型的。

现代的静态语言,搞了很好的“伪装”,使它写起来可以非常的有“动感”,例如 C#3,Scala等,但究其本质,它们代码中涉及的类型,仍然是可以编译期确定的。我所接触过的语言中,此类功能最有历史的应该是Haskell,而它是通过一个非常严苛的数学体系来推导类型,在此过程中,还是时有需要程序员显式声明函数类型,才能完成编译。

静态语言在变得越来越友好敏捷,动态语言在越来越快,但是两者之间的分界,仍然相当的清晰,静态语言更快,更具优化潜力。动态语言更灵活,更具表达能力。这是两者不能被互相取代的根本原因。

当然,性能问题并不简单,动态语言在宏观上往往没有具部的测试结果看起来那么慢,这是因为要表达复杂的业务逻辑,往往需要复杂的数据结构和访问代码,这些复杂的数据内容,要随着用户的访问不断变化。要实现这一切,如果使用静态语言,就要关注动态数据结构的实现,如果使用的是没有GC的开发技术,还要关注内存资源的回收,确实会出现绕了一大圈儿,结果实现的系统还没有现成的动态语言快的现像(尽管这不是普遍的)。更何况现实中总是以线性读写的IO接口,更严重拉平了不同语言之间的性能差异。所以现在比较得到认可的实现方式往往是以动态语言实现项目,然后,如果有需求,也有这个成本负担,就以静态语言优化性能瓶颈。

当然,上述的模式往往用在服务器型的项目中,在GUI环境中,要与显示器、鼠标键盘等人机交互环境频繁的互动,这个资源付出非常的大,加上在CPP等静态语言大行的时代,GUI开发已经相当成熟,技术力量沉积的历史原因,这个领域仍然是以静态的、编译型的语言为主力。最多是为了提交二次开发能力,提供动态语言调用的接口,或嵌入一个解释环境,有限的利用。其实即使是服务器环境,随着互联网的发展,性能问题也正在越来越突出。我就遇到过某个简单逻辑的功能,使用Python怎样都无法优化到理想的程度,最终用Objective C写了一个nginx模块。另一方面说Objective C这样的语言已经相当的动态化,使用它的字典结构,要比用C方便的多,在二进制上又可以完全兼容于C,在性能和空间付出上,明显可以观察到比大多C的字典结构,要多付出一些性能代价。计算机没有魔法,人得到便利,总是要付出一些计算资源。把它尽可能的贴近理想,是技术人员的目标。

越来越多的大型架构,要求我们不仅以模块、连接库和函数接口的层面思考问题,更多的要考虑实际运行时的,运行实例和服务器的行为。我们不但需要附件齐备的运行时环境,也需要可以直达硬件的,高速有效的工具。包括开发一些不那么动态但是更快速的定制服务环境,也成为一个越来越常见的需求。

虽然编程语言在发展,我们有更多,更强大的方式来表达我们的思维,但是随着用户量、商业模式和服务方式的迅速变化,新的挑战也不断出现。对于职业的IT开发团队,我们在面对更多的挑战。我们需要更为丰富的技术组合,指望一种技术一统天下,即使局限于互联网应用这个领域,也仍然是一个奢望。这十年来动态语言的兴起,其实是在补过去逻辑表达方面不足的功课,这是硬件发展带来的有限的福利,但是硬件资源永远是快速发展,但却不足使用。动态语言和静态语言组合使用,兼顾高效开发与高性能的效果,在目前可以预见的未来,仍然是比较实际的思路。

你可能感兴趣的:(杂谈,语言,objective,c,数据结构,python,haskell,jython)