您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

java为什么比python快

2024/5/27 23:09:03发布22次查看
python慢,这几种是常见的原因:“因为它是gil(全局解释器锁)”,“因为它是解释语言不是编译语言”,“因为它是动态类型语言”。
推荐课程:java教程。
究竟哪个原因对性能的影响最大?
“因为它是gil”
现代计算机的 cpu 有多个核心,有时甚至有多个处理器。为了利用所有计算能力,操作系统定义了一个底层结构,叫做线程,而一个进程(例如 chrome浏览器)能够生成多个线程,通过线程来执行系统指令。这样如果一个进程是要使用很多 cpu,那么计算负载就会由多个核心分担,最终使得绝大多数应用能更快地完成任务。
在撰写本文时,我的 chrome 浏览器开了 44 个线程。另外,基于 posix 的操作系统(如 mac os 和 linux)的线程结构和 api 与 windows 操作系统是不一样的。操作系统还负责线程的调度。
如果你没写过多线程程序,那么你应该了解一下锁的概念。与单线程进程不同,在多线程编程中,你要确保改变内存中的变量时,多个线程不会试图同时修改或访问同一个内存地址。
cpython 在创建变量时会分配内存,然后用一个计数器计算对该变量的引用的次数。这个概念叫做“引用计数”。如果引用的数目为 0,那就可以将这个变量从系统中释放掉。这样,创建“临时”变量(如在 for 循环的上下文环境中)不会耗光应用程序的内存。
随之而来的问题就是,如果变量在多个线程中共享,cpython 需要对引用计数器加锁。有一个“全局解释器锁”会谨慎地控制线程的执行。不管有多少个线程,解释器一次只能执行一个操作。
这对 python 应用的性能有什么影响?
如果应用程序是单线程、单解释器的,那么这不会对速度有任何影响。去掉 gil 也不会影响代码的性能。
但如果想用一个解释器(一个 python 进程)通过线程实现并发,而且线程是io 密集型的(即有很多网络输入输出或磁盘输入输出),那么就会出现下面这种 gil 竞争:
如果 web 应用(如 django)使用了 wsgi,那么发往 web 应用的每个请求都会由独立的 python 解释器执行,因此每个请求都只会有一个锁。由于 python 解释器启动很慢,一些 wsgi 实现就支持“守护模式”,保持 python 进程长期运行。
“因为它是解释语言”
这条理由我也听过很多,我发现它过于简化了 cpython 的实际工作原理。当你在终端上写 python myscript.py 时,cpython 会启动一长串操作,包括读取、词法分析、语法分析、编译、解释以及执行。个过程的重点就是它会在编译阶段生成.pyc文件,字节码会写到__pycache__/下的文件中(如果是python 3),或者写到与源代码同一个目录中(python 2)。不仅你编写的脚本是这样,所有你导入的代码都是这样,包括第三方模块。
因此绝大多数情况下(除非你写的代码只会运行一次),python是在解释字节码并在本地执行。与java和c#.net比较一下:
java将源代码编译成“中间语言”,然后java虚拟机读取字节码并即时编译成机器码。.net cil也是一样的,.net的公共语言运行时(clr)使用即时编译将字节码编译成机器码。
那么,既然它们都使用虚拟机,以及某种字节码,为什么python在性能测试中比java和c#慢那么多?第一个原因是,.net和java是即时编译的(jit)。
即时编译,即jit(just-in-time),需要一种中间语言,将代码分割成小块(或者称帧)。而提前编译(ahead of time,简称aot)是编译器把源代码翻译成cpu能理解的代码之后再执行。
jit本身并不能让执行更快,因为它执行的是同样的字节码序列。但是,jit可以在运行时做出优化。好的git优化器能找到应用程序中执行最多的部分,称为“热点”。然后对那些字节码进行优化,将它们替换成效率更高的代码。
这就是说,如果你的应用程序会反复做某件事情,那么速度就会快很多。此外,别忘了java和c#都是强类型语言,所以优化器可以对代码做更多的假设。
“因为它是动态类型语言”
“静态类型”语言要求必须在变量定义时指定其类型,例如c、c++、java、c#和go等。
而动态类型语言中尽管也有类型的概念,但变量的类型是动态的。
a = 1a = foo
在这个例子中,python用相同的名字和str类型定义了第二个变量,同时释放了第一个a的实例占用的内存。
静态类型语言的设计目的并不是折磨人,这样设计是因为cpu就是这样工作的。如果任何操作最终都要转化成简单的二进制操作,那就需要将对象和类型都转换成低级数据结构。
python帮你做了这一切,只不过你从来没有关心过,也不需要关心。
不需要定义类型并不是python慢的原因。python的设计可以让你把一切都做成动态的。你可以在运行时替换对象的方法,可以在运行时给底层系统调用打补丁。几乎一切都有可能。
而这种设计使得python的优化变得很困难。
那么,python的动态类型是否让python更慢?
比较并转换类型的代价很大。每次读取、写入或引用变脸时都会检查类型
动态类型的语言很难优化。许多替代python的语言很快的原因就是它们牺牲了便利性来交换性能。
例如cython(http://cython.org/),它通过结合c的静态类型和python的方式,使得代码中的类型已知,从而优化代码,能够获得84倍的性能提升
总结
python慢的主要原因是因为它的动态和多样性。它能用于解决各种问题,但多数问题都有优化得更好和更快的解决方案。
但python应用也有许多优化措施,如使用异步、理解性能测试工具,以及使用多解释器等。
对于启动时间不重要,而代码可能享受到jit的好处的应用,可以考虑使用pypy。
对于代码中性能很重要的部分,如果变量大多是静态类型,可以考虑使用cython。
以上就是java为什么比python快的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product