我们要先说明计算机语言的一个基本哲理:抽象,提升编写速度,降低运行速度。此处抽象的含义与其本义一致:从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征的过程。
计算机语言差不多可以分为三级,从底层到高层依次是机器语言、汇编语言、高级语言。什么叫底层?底层就是抽象程度低,高层就是抽象程度高。
机器语言差不多长这个样子:
100011001010101111100111110000011100111110011
这一级几乎是没有经过任何抽象的。机器语言仅仅只是将“开”和“关”转化成了1和0. 可以说机器语言根本就不具有阅读意义。但是,机器语言是仅有的、可以被机器直接理解的形式,其余任何形式——比如汇编语言和高级语言——都是要经过转化,或者说解释的。这就意味着机器语言的执行无比之快。
汇编语言抽象的程度更高,它长这个样子:
S_T:
MOV AX,C_S
MOV DS,AX
LEA DX,P_S
MOV AH,9
INT 21H
虽然对于现代的很多程序员来讲,这种写法或多或少还是令人费解的,但它终于有规律可循了——但它也同时有代价。万事万物,都有代价。此处说的不只是计算机语言,说的是这个世界的任何东西。汇编语言虽然提升了可读性,但是它不是机器能直接理解的形式,它需要经过一次转化。
高级语言,是很多人现在最主要接触,乃至唯一接触的语言,C、Python、Java、Rust,你现在能听到的语言基本都是高级语言。以一个很多人都很熟悉的C++程序为例,高级语言长这个样子:
#include <iostream>
int main(void)
{
std::cout<<"Hello World!"<<std::endl;
return 0;
}
比起汇编语言,高级语言显然又“有人文色彩”了不少,事实上高级语言也往往确实比汇编语言更好理解。但是,当然,这是有代价的。比起汇编语言,它又进行了一次抽象,它需要更多转化才能让计算机执行。
这就是计算机语言的基本哲理:抽象,提升编写速度,降低运行速度。你提升了可读性,你往往要降低运行性。
高级语言之间的抽象程度不一样,C的抽象程度低于Python的抽象程度——这是C比Python困难的一大原因,这是Python比C运行速度低的一大原因,而我现在要问的是,Python带来的抽象程度和Python带来的执行效率降低相比,值不值得?
我们活在这样一个时代——一个计算机性能过剩的时代:除去少数优化声名狼藉以至于天下人皆知的游戏之外,当你的电脑跑不起某一款游戏时,大家往往会说“快换个显卡吧”、“加个内存条”,而不是说“没办法,游戏优化太烂了”,即使有时候游戏优化确实大有精进之处。大家会因为什么去购买游戏呢?在“游戏优化很好”和“游戏内容很多”之间,大家一般会选择“游戏内容很多”,而后,在“游戏内容很多”的前提下,大家发现它的优化还做得不错,就会将“游戏优化很好”作为添头加上去。不仅是游戏如此,很多常用的APP也是如此。这就是我们的时代。
我不是说这种时代有错。它没错。我只是说,在这样一种时代之中,追求性能的优先度确凿无疑地下降了,但是它绝对不是无关紧要的。比起C、Java等语言,Python的抽象程度高了一些,难度低了一些,但是性能到底下降了多少?下降得太多了。当然,Python有Cython这样的支流,但是Cython比起C,又抽象了多少,性能变化了多少?这是一个找到平衡的问题,而我给出的平衡答案就是C++这一级的抽象较为可取,Python这一级较为不可取。
上文说的是C(系)和Python这两种语言的一些本质问题,我们下面再谈谈我为什么坚决反对让新手先学Python.
Python的很多功能,很多为人称道的“便利性”,或多或少地像是某种甜口毒药。“不要重复实现轮子”的预期之一是术业有专攻,可能甲就是不擅长数据处理,乙就是不擅长UI界面,那么大家互相把自己擅长的东西拿给对方就好,这样才能团结人类的智慧——“不要重复实现轮子”的预期,不是说不要去写已经有过的东西,而是不要白白去写已经有过的东西。Hello World的写法早已不可计数,但新手程序员还是常常会第一个写它,因为这样一个小小的程序包含了“输出”的概念,在有些案例中还会包含“输入”,写它是一个学习的过程。Python有海量的库,这很好,这也很不好,说到这里,大家已经明白为什么它既好又不好了,而且尤其对有上进心的新手不好。让新手大量使用库的最终结果,就是社会上多出了一批脚本小子,而我不喜欢这样。
最后,我说Python低贱是有个人因素在的。看着Python开发团队将自己当年所讥讽的C系拥有的一些feature重新加回Python,我总是觉得趣味十足又余韵悠长。