Python的“虚拟机”似乎很少读到,而在Java中“虚拟机”一直被使用。
两者都解释字节码;为什么一个叫虚拟机,另一个叫解释器?
Python的“虚拟机”似乎很少读到,而在Java中“虚拟机”一直被使用。
两者都解释字节码;为什么一个叫虚拟机,另一个叫解释器?
当前回答
HotSpot运行时被称为虚拟机,而CPython仅仅被称为解释器,这可能是有原因的
首先,CPython只是普通的、基于栈的字节码解释器。你向它输入Python操作码,CPython内部的软件堆栈机器就会计算你的代码,就像普通的解释器一样。
The Java HotSpot runtime is different. First and foremost, Java has 3 Just-in Time Compilers, C1, C2, and an experimental one that isn't in use yet. But that's not the main reason. The Interpreter inside the JVM is a very special kind of Interpreter called a Template Interpreter. Instead of just executing bytecode directly in a massive opcode switch case statement like CPython (And really almost every other interpreter does) does, the Template Interpreter inside the JVM contains an enormous arraylist. What does it contain? Key-value pairs of bytecodes and native CPU instructions! The arraylist is empty on startup and is filled with mappings of bytecodes pointing to native machine language to be directly run on the hardware just before your application starts up, what this means is that the "Interpreter" inside the JVM isn't actually an Interpreter at all- It's actually a discount Compiler! When Java bytecode is run, the "Interpreter" simply maps the input bytecode directly to native machine language and executes the native mapping directly, rather than implementing it in software. I'm not exactly sure why the JVM was made this way, but I suspect it was to easily execute "Interpreted" Code together with JIT Compiled Code seamlessly, and for speed/performance. If you pitted the JVM without JIT against CPython or most other interpreters it would still probably come out ahead of them, in virtue of its ingenious design which to my knowledge no other language has used before.
其他回答
他们之间没有真正的区别,人们只是遵循创造者选择的惯例。
我认为两者之间的界限是模糊的,人们大多争论的是“解释器”这个词的含义,以及语言与“解释器……编译器”范围的每一方有多接近。然而,没有一个是100%的。我认为编写Java或Python实现是很容易的,这是频谱的任何价值。
目前Java和Python都有虚拟机和字节码,尽管一个操作具体的值大小(如32位整数),而另一个必须确定每次调用的大小,在我看来,这并没有定义术语之间的边界。
Python没有正式定义的字节码,它只存在于内存中,这一论点也不能说服我,只是因为我计划开发只识别Python字节码的设备,编译部分将在浏览器JS机器中完成。
性能只与具体的实现有关。我们不需要知道对象的大小就能处理它,最后,在大多数情况下,我们处理的是结构,而不是基本类型。可以通过重用现有对象来优化Python VM,从而消除每次在表达式计算期间创建新对象的需要。一旦完成,在计算两个整数的和之间没有全局性能差异,这是Java的闪光点。
两者之间没有致命的区别,只有一些与最终用户无关的实现上的细微差别和缺乏优化,可能在她开始注意到性能滞后的时候,但这又是实现而不是架构的问题。
Python可以解释代码,而无需将其编译为字节码。Java不能。
Python是一种解释型语言,而不是编译型语言,尽管由于字节码编译器的存在,两者的区别可能很模糊。这意味着源文件可以直接运行,而无需显式地创建一个可执行文件,然后再运行。
(来自文档)。
在java中,每个文件都必须编译为.class文件,然后在JVM上运行。相反,python会通过主脚本导入这些文件,以帮助加快后续使用这些文件的速度。
然而,在典型的情况下,大多数python(至少是CPython)代码运行在模拟的堆栈机器中,它与JVM的指令几乎相同,因此没有太大的区别。
然而,这种区别的真正原因是,从一开始,java就把自己打上了“可移植的、可执行的字节码”的标签,而python则把自己打上了带有REPL的动态解释语言的标签。名字贴!
for posts that mention that python does not need to generate byte code, I'm not sure that's true. it seems that all callables in Python must have a .__code__.co_code attribute which contains the byte code. I don't see a meaningful reason to call python "not compiled" just because the compiled artifacts may not be saved; and often aren't saved by design in Python, for example all comprehension compile new bytecode for it's input, this is the reason comprehension variable scope is not consistent between compile(mode='exec, ...) and compile compile(mode='single', ...) such as between running a python script and using pdb
术语解释器是一个遗留术语,可以追溯到早期的shell脚本语言。由于“脚本语言”已经演变成功能齐全的语言,它们对应的平台也变得更加复杂和沙箱化,虚拟机和解释器(在Python意义上)之间的区别非常小,甚至不存在。
Python解释器仍然以与shell脚本相同的方式运行,从某种意义上说,它可以在不需要单独的编译步骤的情况下执行。除此之外,Python解释器(或Perl或Ruby的)和Java虚拟机之间的区别主要是实现细节。(有人可能会说Java比Python更加完全沙箱化,但两者最终都通过原生C接口提供对底层架构的访问。)