从多线程的角度考虑
Python中存在GIL全局锁,仅允许一个线程持有Python解释器的控制权;这意味着在任何时间点只能有一个线程处于执行状态;而C++和Java都可以同时有多个线程执行。
从语言特性上来看
Python是动态语言,每个变量都是一个指针(PyObject *),它可以指向任意的对象,无法只针对基于类型方面做优化,所以有相当一部分时间浪费在类型和属性的查找上面。
以变量a + b为例,这个a和b指向的对象可以是整型、浮点型、字符串、列
表、元组、甚至是我们自己实现了某个方法的类的实例对象。在计算a+b时,首先Python要判断变量到底指向的是什么类型,这在C级至少需要一次属性查找。然后Python将每一个操作都抽象成了一个方法,所以实例相加时要在对应的类型对象中找到该方法对应的函数指针,这又是一次属性查找。找到了之后将a、b作为参数传递进去,这会发生一次函数调用,会将a和b中维护的值拿出来进行运算,然后根据相加结果创建一个新的对象,再返回其对应的PyObject *指针。而对于C++来讲,由于已经规定好了类型,所以a + b在编译之后就是一条简单的机器指令,所以两者在效率上差别很大。(参考自知乎)
从解释执行的角度看
Python的解释器CPython没有即时编译(JIT),Python虽然是解释性语言,在编译阶段生成.pyc文件,运行时解释字节码在本地运行,但是Java会进行即时编译。
JIT技术:当JVM发现某个方法或代码块运行特别频繁的时候,就会认为这是“热点代码”,然后JIT会把部分热点代码编译成本地机器相关的机器码,并进行优化,然后再把编译后的机器码缓存起来,以备下次使用。