• 0
  • 新人请关照

java为什么比python快?

想了解代码从编译到执行的这个过程, 前辈们具体帮我们做了什么工作?
不想听到因为java是静态语言啊, python是动态语言啊, 静态语言就是比动态语言快啊, 这种直接用一句话下总结的回答

阅读 2.5k
评论
    6 个回答

    无意义的问题,自己不去学习,百度一搜就能深入了解

      • 12k

      这要从 CPU 说起,CPU时能够执行一些基本操作的硬件,比如加减乘除读写内存、堆栈管理、跳转之类的基本操作。CPU要执行的下个动作是在内存中读取的二进制数据,所以最初的编程是编写这个二进制的程序,然后放到内存里让CPU执行(先不要问题怎么放以及放到哪里的问题)。

      可是人类很难识别二进制,于是就出现了汇编语言,他的语句与二进制的指令一一对应,仅仅是用一些“单词”之类的东西替换原本的二进制指令。“编译器”仅仅把“单词”替换城二进制代码,CPU就可以执行。

      但是CPU执行的操作太基本了,比如连循环这种东西都没有(可以使用判断+跳转实现),再比如存储数据就是预留点儿内存(就是随便写点儿二进制代码,并且小心的控制代码执行,并不让代码执行这里的“指令”),直接按照内存地址读写对应的内存数据,一不小心就会计算错了地址(不同的数据可能占用不同数量的内存)。于是就有了一种高级语言,这种语言把程序总结为顺序,分支,循环等流程,当写下了某种结构,编译器按照固定的模板把对应的流程编译成二进制指令(这个模板为了通用,可能会牺牲一些效率);在这种语言中,当我们需要一个地方存储数据,那么就可以定义一个叫做变量的东西,然后把数据存在变量里。编译时编译器就会像汇编里那样预留一些内存,把对变量的读写编译为对对应内存的读写;以及该语言...可以分多个文件写代码...提供一些常用的代码片段(标准库)...等等很多功能。当然还有很多跟该语言竞争的其他语言,他们提供了更加丰富的功能和标准库。。。

      但计算机如何管理不同的程序,分配可用资源,比如CPU、内存等,呢?于是我们发明了一个叫做操作系统的东西,他会帮我们根据我们可执行文件里的信息(例如,exe里除了保存二进制代码还保存了把代码加载到哪个内存地址等其他信息)把我们的二进制代码加载到对应的内存,并且初始化相应的内存。操作系统为了管理这些东西也会牺牲一些效率(比之前手动管理)。

      感觉很完美了,但是还有问题,那就是不同的CPU有不同的控制指令,而且不同的操作系统也需要不同的应用程序格式,这样我们的程序就不通用了~。于是出现了一种“操作系统”,这种“操作系统”安装在其他操作系统之上,不同的操作系统需要安装不同版本的该“操作系统”, 此“操作系统”虚拟了出了一套”基本指令“,当执行某条”基本指令“时此”操作系统“把该指令现场根据所在操作系统选择合适的模板,然后按照该模板执行一系列该操作系统和CPU上的指令(模板为了通用,以及”基本指令“的现场翻译使得该”操作系统“不得不牺牲一些效率)。”基本指令“对人来说也不是很友好,所以该”操作系统“也研发出自己的一套高级语言,并提供了编译器把此高级语言翻译成该”操作系统“上的”基本指令“。

      但是,编译器一旦编译完,我就再也没有办法修改这个程序了(除非重新编译)。可是很多时候,我做实验的时候,写下一句代码的时候我们依旧不知道下一句我将要怎么写。于是,我需要一种我写完一句代码,它立即翻译成”基本指令“并执行的语言。这样我就可以执行一句代码,看一下结果,然后决定下一局该怎么写了(由于这种语言在执行的时候把代码翻译成”基本指令“的操作,而且还要执行完这句能让你直接看看当前的结果,以及它不知道将来还需要大的空间存储数据,再以及它要提供更加强大的功能,所以不得不牺牲一些效率)。当我做完实验,知道整个程序该怎么写就可以把整个程序写到一个文件里。由于该语言没有提供编译器(其实可以提供),它依旧是从文件读取一句,翻译一句,然后执行一系列操作,再读下一局...这样的方式执行。

        知识背景

        1. 机器只能执行机器码,也就是010101这种。
        2. 解释:拿到源文件边翻译为机器码边执行。
        3. 编译:执行前翻译为机器码并保存,执行的时候就直接执行机器码
        4. JIT(即时编译):程序启动时还是解释执行,如果发现某代码执行的特别频繁就翻译为机器码,后续执行该代码时不翻译,直接执行机器码

        问题解析
        java编译器把java代码编译为class文件,JVM解释执行,发现热点代码则编译为机器码执行。
        python是解释执行,需要经过翻译步骤,肯定比直接执行机器码要慢

          python实际上是每一句都是c实现的, 运行的时候就是解析脚本, 调用对应的函数, 传入参数, 得出结果这样子. 所以原生支持编译成exe.
          java本身是编译成class, 运行起来还是调方法, 传参数. 不过是不用语法解析, 毕竟编译已经编译过了.早期java其实也慢的, 后来是逐渐优化才快起来的.
          像有个优化方式就是: 经常用到的部分,jvm(java虚拟机)会将其编译成机器码以加快执行速度..

            哈哈,这不是十年前 C语言和java的区别吗?

              • 0
              • 新人请关照

              Python的解释器和虚拟机翻译并执行字节码的过程带来了很大的性能开销,一个直觉的解释是:由于没有原生的编译时类型检查,所有的类型的检查都被移交给了运行时,执行一行Python代码很可能需要做不只一行的类型检查、边界检查等等。
              转自 https://zhuanlan.zhihu.com/p/...

                撰写回答

                登录后参与交流、获取后续更新提醒