为什么python运行的慢
最近在leetcode刷题,明显的注意到同样的算法,python运行的要慢的多,查资料得到python运行的慢主要原因如下:
一、动态类型导致运行速度慢,在北邮人论坛里面的这篇帖子中有较为详细的解释,原文中有举例说明,本文没有例子讲解只是提取了原理来讲解,内容主要如下:
(原文链接:http://bbs.byr.cn/#!article/Python/68)
a、动态语言中的执行过程
Python等动态类型语言之所以慢,就是因为每一个简单的操作都需要大量的指令才能完成。他们的虚拟机拥有很强的优化器,却是为静态语言设计的。对Python几乎没有效果。举一个例子。对于整数加法,C语言很简单,只要一个机器指令ADD就可以了,最多不过再加一些内存读写。但是,对于Python来说,a+b这样的简单二元运算,可就真的很麻烦了。Python是动态语言,变量只是对象的引用,变量a和b本身都没有类型,而它们的值有类型。所以,在相“加”之前,必须先判断类型。
1. 判断a是否为整数,否则跳到第9步
2. 判断b是否为整数,否则跳到第9步
3. 将a指向的对象中的整数值读出来
4. 将b指向的对象中的整数值读出来
5. 进行整数相加
6. 生成一个新整数对象
7. 将运算结果存进去
8. 返回这个对象,完成!
9. 判断a是否为字符串,否则跳到第13步
10. 判断b是否为字符串,否则跳到第13步
11. 进行字符串串接操作,生成一个新字符串对象
12. 返回这个对象,完成!
13. 从a的字典里取出__add__方法
14. 调用这个方法,将a和b作为参数传入
15. 返回上述方法的返回值。
这还只是简化版的,实际中还要考虑溢出问题等。
b、Jpython
Jython能做的只是把Python代码转换成JVM的代码,而Python中那些判断a,b是否为整数或者字符串的操作是不能省略的。毕竟Python是允许你写1+2同时也可以"hello"+"world"。这种运行时的类型检查并不能简单地通过编译而去除。
c、谷歌的Unladen Swallow项目
它是一个很有雄心的项目,但是,在项目开始一年后就流产了。最后,加速效果也不过50%左右。它们使用的方法是朴素的“模板编译法”:看到Python的加法操作,就转换成一个C语言的函数调用,调用Python的PyNumber_Add函数。这个函数就是干类似上面一串的事。同样地,虽然去除了官方Python的解释器代价,但并没有消除运行时类型检查的代价。
d、pypy为什么比较快和pypy的不足:
PyPy可以将Python的速度加到C的一半左右。PyPy使用了一种技巧,就是“类型推导”(Type Inference)。PyPy的运行时编译器(Just-in-time compiler,或者称JIT Compiler)的工作方式是,只优化循环,因为大量的时间都是消耗在少数循环上。当运行时检测到某个循环运行的次数很多的时候,就开启一个“录像机”,录制这个循环执行一次中,执行的所有操作的轨迹。这样以“轨迹”为单位的编译方式叫Tracing JIT。当类型确定以后,其中涉及的数据都是整数,都可以直接对应机器指令进行执行。程序起码在这一部分已经由动态的代码变成像C一样的静态类型代码了,而且数据类型很接近机器。将这一段代码编译成机器码,效率就可以和C相比了。
注意到,这其实是一种“猜测”:优化器“猜想”每次执行循环for i in range(n),i和n都是整数。这种猜测是可能出错的。万一程序员将一个字符串传入函数怎么办呢?所以,基于“猜测”(speculation)的优化必须考虑“猜错了”的情形。这就是优化过的代码的第1、3、11行的用途。1和3考虑万一i和n不是整数的情形,而15考虑了整数溢出的情况。在Python里,整数都是高精度整数,可以是任意大的,而不仅限于32位。(其实上述32位也只是假设,在64位机上,显然64位效率更高。)所以,如果猜错了(这种事经常会发生),就必须停止执行这段“优化”过的代码,而是老老实实回到解释器中,像传统的Python一样执行。
可以看出,带有类型推导功能的Tracing JIT编译器可以大幅度加快动态语言的速度。主要原因是:
1. 在运行时得到了变量的类型,并通过“猜测”,将这些类型转换成接近机器的类型。
2. 将简化的操作编译成机器码,去除了解释器的代价。
目前,PyPy是一个很活跃的项目。但是,毕竟是一个研究型的项目,PyPy也有自己的不足。如和官方Python并不完全兼容;PyPy本身的可执行文件很大;并不是运行所有的程序都快——PyPy虽然JIT Compiler很快,但它的解释器速度不如官方的Python,对于无法通过优化加速的程序来说,PyPy就不快了。
二、python慢不仅是因为动态类型,甚至不是python慢的主要原因,在现实中,在C语言和Python在运行时的巨大的不同是由于数据结构和算法的不同。
原文链接:http://ourjs.com/detail/5320393ab79767cf7b000004
用Python写不同的代码
point = {'x': 0, 'y': 0}
struct Point {
int x;
int y;
};
std::hash_set point;
point[“x”] = x
point[“y”] = y
class Point(object):
x, y = None, None
def __init__(self, x, y):
self.x, self.y = x, y
def sum_(points):
sum_x, sum_y = 0, 0
for point in points:
sum_x += point['x']
sum_y += point['y']
return sum_x, sum_y
为什么python运行的慢的更多相关文章
- Python黑帽编程1.3 Python运行时与包管理工具
Python黑帽编程1.3 Python运行时与包管理工具 0.1 本系列教程说明 本系列教程,采用的大纲母本为<Understanding Network Hacks Attack and ...
- Java和Python运行速度对比
Java和Python运行速度对比:同一个函数运行一百万次,Java耗时0.577秒,Python耗时78秒--135倍的差距. 版本:Java 8,Python 2.7.10 Java测试代码: i ...
- python 运行python manege.py runserver时报错:“no module named djangorestframework” 的解决方案
python 运行python manege.py runserver时报错:“no module named djangorestframework” 的解决方案 importerror:no mo ...
- Python运行Google App Engineer时出现的UnicodeDecodeError错误解决方案
#Python运行Google App Engineer时出现的UnicodeDecodeError错误解决方案 ##问题描述 使用Python2.7.x运行GAE时有时会报这个错误 ```py ...
- 自动化测试 Appium之Python运行环境搭建 Part2
Appium之Python运行环境搭建 Part2 by:授客 QQ:1033553122 实践环境 参见 Appium之Python运行环境搭建 Part1 环境部署 1.安装Android SDK ...
- 自动化测试 Appium之Python运行环境搭建 Part1
Appium之Python运行环境搭建 Part1 by:授客 QQ:1033553122 实践环境 Win7 Python 3.4.0 JAVA JDK 1.8.0_121 node.js8.11. ...
- day2 编程语言介绍、Python运行程序的两种方式、变量
一 编程语言介绍 1. 机器语言 用计算机能理解的二进制指令直接编写程序,直接控制硬件 2. 汇编语言 用英文标签取代二进制指令编写程序,本质也是直接控制硬件 3. 高级语言 用人能理解的表达方式去编 ...
- 用 virtualenv 创建隔离的 Python 运行环境
以 Ubuntu 14.04 系统为例,安装的 Python 和 Python3 分别是 2.7.6 和 3.4.3, 但有些项目,有些模块要求特定的 Python 版本.而当前系统默认的 Pytho ...
- 隔离python 运行环境和Pycharm 设置代码同步
隔离python 运行环境 查看当前有哪些虚拟环境:workon 进入虚拟环境:workon django 退出虚拟环境:deactivate 创建虚拟环境: mkvirtualenv -p /usr ...
随机推荐
- Java 引用数据类型
引用数据类型 * A: 数据类型 * a: java中的数据类型分为:基本类型和引用类型 * B: 引用类型的分类 * a: Java为我们提供好的类,比如说:Scanner,Random等. * C ...
- CodeForces632E 神奇的多重背包
https://cn.vjudge.net/problem/333897/origin 万万没想到这题表面上是个多重背包,实际上确实是个多重背包 题意 n种物品每种物品有无限个,每个物品有一个价格,现 ...
- Zabbix Server 自带模板监控更加灵活MySQL数据库
Zabbix Server 自带模板监控更加灵活MySQL数据库 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.zabbix-agent端配置 1>.修改zabbix的 ...
- Netsarang
下载 https://www.netsarang.com/zh/all-downloads/ 建议直接下载 xmanager-power-suite,里面包含了 Xmanager.Xshell.Xft ...
- Spark源码剖析 - SparkContext的初始化(五)_创建任务调度器TaskScheduler
5. 创建任务调度器TaskScheduler TaskScheduler也是SparkContext的重要组成部分,负责任务的提交,并且请求集群管理器对任务调度.TaskScheduler也可以看作 ...
- 微信小程序,错误{"errMsg":"request:fail 小程序要求的 TLS 版本必须大于等于 1.2"}
解决方法一: 开发环境,项目--->勾选不校验即可 解决办法二: 在 PowerShell中运行以下内容, 然后重启服务器 # Enables TLS R2 and Windows # Thes ...
- vue watch bug记录
watch中,写箭头函数,获取不到正确的this 换成function,正确取到this
- tomcat cluster配置实战注意事项
关于tomcat cluster的实现原理,详见:https://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html#How_it_Works. 在 ...
- (15)DeleteColumnsMakeSortedIII
一.问题描述 给定一个字符串形的数组,求最小的删除数目,使得删除后的字符串是字典型有序的. 二.思路Code package algorithm; /** * Created by adrian.wu ...
- 查看 Centos 7 的MAC 地址
查看 Centos 7 的 MAC 地址 ens*** 网卡名称# cat /sys/class/net/eno16777736/address 查看内核版本 uname -a 查看系统版本 ca ...