Perception

Notes taken during the learning process

个人体验

入门

使用Julia已经两年有余了,在这个社区里借助一门新兴的语言我学习了众多关于编程的知识。在各式各样的讨论中,我也明白了为什么我要使用Julia,同时如何理解事物的迭代和相互之间的关系。

那是一个幸运的相逢。2018年末的某天早上爬起来翻朋友圈,看见伟钰发了一条朋友圈:Julia1.0正式发布。当时我还是个重度MATLAB用户,科研生产大型程序使用的是Fortran,懂一点Python和C,根本不知道Julia是什么。抱着一肚子好奇我点开了官方网站,快速浏览了一下主要的介绍。我至今记得Jeff那段豪言壮志,关于永不满足的程序员宣言。We are greedy. We want more。我下载了新鲜出炉的Julia1.0,在我的Mac上玩儿起来,从此一发不可收拾。那一刻就仿佛罗密欧遇见了朱丽叶,我已为之倾醉。

爱上她有几个原因:

  1. 我对MATLAB非常熟悉,各种加速技巧都有所涉猎。Julia当头一棒就告诉我,为什么即使是动态语言,纯循环也可以比向量化更快。

  2. 数学上的可读性非常好,比之向量化的写法更容易理解。这一点往往会被忽视:在MATLAB和numpy的使用技巧上,用向量化替代循环是最核心的手段;而往往为了追求极致的效率,最终的代码会包含大量类似线性代数的操作,可以说是在没有注释的情况下完全无法理解的代码。

  3. Julia的语法习惯和MATLAB非常接近,也采用了1开头的数组序列,非常方便我将Fortran和MATLAB的已有代码进行改写。

  4. 同时她吸收了Python中的诸多概念,比如list comprehension,dictionary等等,对于已有的大量开源Python代码非常亲切。在使用过程中我能明显地觉察到这些科学界流行的语言对于Julia的影响,也在后续的学习过程中逐步了解了有关各项借鉴的讨论和争议。

  5. 博采众长的编程概念的引入,使得我有机会接触更多现代语言发展的概念。

  6. 我非常喜欢的一部科幻作品《星际牛仔》(Bebop Cowboy),主人公之一Jet的老家是Ganymede,而男主Spike的恋人名叫Julia。研究Ganymede是我博士期间的主要工作,而靠Julia来实现,真是冥冥中注定的缘分。

没几天我很快意识到,独树一帜的风格和兼收并蓄的气质使得这门语言的潜力非常巨大。为了实践测试到底有多大的性能提升,我陆续把以前写过的MATLAB项目重做了一遍,CFD、PIC、MHD、数据读写等等。每次的第一个版本往往效率没什么提升,甚至还会更慢,但经过几轮调试和改进,最终都能达到5倍以上的提高。同时我也做了和Fortran/C的对比,大体上最差慢3倍,好的话接近一致,甚至部分测试Julia更快(比如从SpacePy借鉴来的磁力线追踪模块,就是Python调用C)。经此,我完全相信她已经具备了在效率上和任何市面上的头部产品竞争的实力。在并行计算部分,甚至MATLAB和Python都完全不是对手,必须要C/C++/Fortran来接招才管用。

当然这过程并非一帆风顺。正是由于她的年轻,更新速度快,引入了很多不向前兼容的设计,使得诸多已有的档案介绍都是不能运行的,甚至很多工具包都不能运行或者出现各式各样的错误。在检查和搜索某些功能该如何使用的过程中,我一点点地了解到了很多东西是如何演变的,以及为什么现在会比以前好。学习都是有成本的,但这些付出是我认为值得的。

Maybe one day C++ and Julia will also be replaced by even better programming languages. We should stay humble and stay foolish. 学习的路上没有尽头,接纳新鲜事物,才不会变成老古董。三十年前,Fortran如日中天,Combol江河日下,C++初出茅庐,甚至还有文章专门论证面向对象编程效率不是瓶颈。如今Fortran世风日下,C++风头正劲,Python一时无二,Julia初来乍到,前浪后浪总在交替变化。当我回顾程序语言发展的历史,我意识到动态编译语言的出现是非常自然而然的,只不过其中的佼佼者叫Julia而已。当二十年前UIUC开始鼓捣LLVM框架时,这套现代的编译模块化系统便为日后的Julia的诞生铺好了路。Python出生的时代,目之所及全是晦涩难懂的编译语言,而她一扫人们对于编程的恐惧,终于在三十年后成为流行风尚。历史为鉴,可以知兴替。如果用一句话来概括Julia的成长史,那么就是她的诞生和如今的成长像人们证明了动态语言本身并不是构成制约速度的主要问题,正如面向对象并非绝对的速度瓶颈一样。

在网上你可以看见各式各样的论战,哪种语言是最优秀的语言自然也是硝烟弥漫的战场之一[1]。在讨论争辩之余,扬长避短才是我们应该秉持的态度,而不是一味地为某门语言站台。在我最开始接触Julia的时候,网上有一篇搜索前列的文章,“Why I abandoned Julia”。这篇文章的作者详细描述了Julia存在的诸多问题,并最终选择暂时放弃使用。Julia的核心开发人员们选择了直面问题,并没有因此气馁,因为他们对自己的技术有自信,需要的是时间来完善。在若干年后的今天,许多问题已经得到了可见的提升。这条赛道上并非只有Julia,还有CPython,PyPy,Numba,LuaJIT甚至MATLAB等等,但我们看到没有历史包袱的Julia目前站在了领先的位置。兼容历史悠久的程序并引入新技术并非易事,在Python中加入JIT尝试的核心阻碍就是这里。这些年我也看到Python,MATLAB,和Mathmatica都在不断进步,比如函数的参数类型已经都可以制指定了,比如都引入了调用CUDA的方法,MATLAB转C++和CUDA的翻译包也有了,甚至2020年Mathmatica也可以生成LLVM代码了。在碰撞和融合中,我们将会迎来下一代的计算语言。

其实在编程语言界有很多不太为人知的优秀作品,比如Haskell的纯函数编程,比如变魔法一样的Wolfram Alpha。在浏览各种帖子中,我也略微了解了smalltalk,Rust,Go等等。我们对于美的追求没有尽头。

曲折

我陶醉其中不等于大家都能接受。我跟我周遭的人都提过这门语言,但是最终可能只有我自己在使用,其他人连尝试都没有。把自己喜欢的东西分享给别人十分快乐,可是不是所有人都能接受同样的快乐。我的博士导师办公室里摆了一本Python编程指南,是曾经系里另一位年轻老师送给他的,可估计他一次都没翻过就摆上书架了。对他而言,Fortran+Perl+IDL就足够解决所有问题了,不需要额外的工具了。那感觉就像给中世纪的骑士介绍火枪有多么好用,可真拿起来总会感觉有些格格不入一样。我尝试过很多次向别人推荐使用Julia,可都无功而返。一次次的失落让我领悟到强扭的瓜不甜,而真正有兴趣的人,你无须多言他自然明白。最终会让人做出决定忍痛割爱选择学习新语言的原因是他们被你能做到的事情和完成的效率所折服,而不是一遍遍夸耀这东西有多好。

忽然我想起了李嘉。他是我周围除了我以外唯一一个使用Julia的人,所以当我们在GPU Computing的课上讨论起Julia的时候,多少有些他乡遇故知的感觉。他跟我说他老板做蒙特卡洛计算的C++程序,他用Julia重写了以后效率反而更高了,恰巧与我改写一维Vlasov模型的经验不谋而合。在求索的路上,我们总要投入更多的时间和精力,做一些前人没有做过的尝试。没有免费的午餐,一切的提升和进步都源于不断地探索和努力。

反思

Julia带给我最大的震撼是什么?不是速度,不是美观,而是可能性。我以前在使用MATLAB、C和Fortran的时候就在想,如果我能做这个这个该多好,后端能调用最底层高效的BLAS代数运算,前端能呈现出一个漂亮的网页或者应用程序。然而这其中的技术壁垒和限制实在是太多,让人感慨于个人能力之有限。Julia是我的启蒙者,告诉我其实并不孤单,也有很多的人在这么想,并且用行动证明了“贪婪”的愿望并非幻想,而是真真切切可以做到的。这群以MIT为核心的原始团队,聚集了一群有野心有能力的年轻人,用令人惊叹的效率进行着开发。从我加入这个社区到现在,有几个名字给我留下了深刻的印象。Jeff Bezanson,创始人,陶醉于技术的、有品位的实干家;Stefan Karpinski,Jeff的老搭档,对Julia相关的各个领域如数家珍,常在论坛上为大家答疑解惑;Chris Rackauckas,可能是写Julia代码最多的人,你在和Julia相关的各个角落都会在不经意间遇到的名字;Viral Shah,Julia Computing运营的负责人,带着印度人独特的沟通魅力尽心尽力地做着语言的推广;Steve Johnson,MIT的计算光学教授,FFTW的开发者,将计算运用于前沿科学的先锋;Yichao Yu,可能是整个社区最硬核的找茬者,常常用我完全不懂的概念一条一条的反驳别人的论述,看得我目瞪口呆;Tim Holy,在各种核心包的开发上贡献了大量出色的铺垫工作,为后继的开发者节省了难以计数的时间......还有更多的名字,Jemeson Nash,Oscar Blumberg,Chris Elrod这些面向更底层代码的不太抛头露面的开发者......Erik Engheim以及其他了解众多语言的特性并能进行比较的人......正是这些人,让这个仅仅十余岁的语言成为计算科学乃至通用编程领域冉冉升起的新星。

另外一点是商业模式的突破。Julia从一开始就决定使用MIT license,也就是所有代码“白嫖”,算是身先士卒地示范了“不靠卖软件赚钱”的想法。MIT license意味着,任何人可以随意使用、改写源代码,甚至用作商业用途,不需要经过原作者的许可。然而这是一群人的态度:语言核心库都是开源的,有什么理由其他新开发的软件包不是开源的?我们还需要践行从上世纪80年代开始的卖代码赚钱的方式吗?但绕不开的问题是:如何赚钱?Julia给出的答案是,服务和资源。其一是为想要使用Julia进行软件迭代或者新功能开发的项目组进行技术支持,从公司或者政府科研经费中抽成;其二是顺应云计算的潮流,搭建稳定高效的针对Julia优化的计算机群,收取使用费用。这两样产生的收益,能够让开发者享受到利益,进而促进整个语言的良性发展,而不会受限于免费还是收费、开源还是封闭的选择困难之中。如果你有技术、有时间、有资源,大可自己撸起袖子加油干;反之,你给我钱,我帮你干,双赢。当你认识到即便在计算机领域,重要的是人而不是代码的时候,或许就不会再纠结于防止剽窃、独享专利一类常见的问题。

打破技术的墙,让所有人为了更好而努力。我相信Julia光明的前途。

[1] "PHP is the best language in the world",出自PHP官方文档,已成为网友调侃此话题的老梗。