作者 | Andrew Zhu

译者 | 苏本如

出品 | CSDN(ID:CSDNnews)

龟兔比赛(我6岁儿子 Charles Zhu 的绘画作品)

人们一直诟病 Python 程序的速度很慢,它到底有多慢呢?

在每次的编程语言速度竞赛中,Python 的名次通常都比较垫底。有人解释这是因为 Python 是一种解释型语言(代码无需编译即可执行),而所有的解释型编程语言执行速度都很慢。然而,我们知道 Java 也是一种解释型语言,它的字节码是由 JVM 解释的。而在这个基准测试速度比较页面上的结果却显示:Java 要比 Python 的速度快得多。

下面是一个可以用来演示 Python 速度慢的示例。它使用传统的 for 循环来产生一个数的倒数:

import numpy as npnp.random.seed(0)values = np.random.randint(1, 100, size=1000000)def get_reciprocal(values):output = np.empty(len(values))for i in range(len(values)):output[i] = 1.0/values[i]%timeit get_reciprocal(values)

结果显示:

每个循环平均耗时3.37秒(标准偏差±582毫秒)(共计运行了7次程序,每次一个循环)

计算 1,000,000 个倒数竟然需要 3.37 秒。使用 C 语言执行同样的运算只需要不到一眨眼的工夫:9 毫秒;C# 需要 19 毫秒;Nodejs 需要 26 毫秒;Java 仅仅需要 5 毫秒!而 Python 竟然用了让人怀疑人生的 3.37秒(它到底做了些什么)!(注:在本文的最后,我附上了所有语言的测试代码)。

Python 速度缓慢的根本原因

我们通常把 Python 称为一种动态类型编程语言。而 Python 程序中的一切变量都是以对象的形式存在,换句话说,每次 Python 代码处理数据时,都需要进行对象拆箱操作,以确定对象的具体类型。在 for 循环内部,每次循环都需要拆箱对象,检查类型并计算倒数。那3秒钟的时间都在类型检查中浪费了。

C 语言和其他传统的编程语言则不同,它们对数据的访问是直接的。但在 Python 中,大量的 CPU 时间都用在了类型检查上。

即使是一个简单的赋值操作也会花费很长的时间。如:

a = 1

这个简单的赋值操作,它需要如下两个步骤:

  • 步骤 1:将 a->PyObject_HEAD->typecode 设置为 Integer 类型.

  • 步骤 2. 将值 1 赋值 a (a->val =1).

关于 Python 为什么速度慢的更多信息,Jake 写的这篇精彩文章值得一读:Why Python is Slow: Looking Under the Hood

那么,有没有一种方法可以绕过类型检查,从而提高 Python 程序的性能呢?

答案是:使用 NumPy 通用函数

与 Python 列表(list)不同,NumPy 数组是围绕 C 数组构建的对象。NumPy 数组访问项不需要任何步骤来检查类型。这给我们找到解决方案指明了方向:使用 NumPy 通用函数(亦即UFunc)。

简而言之,UFunc 是一种可以直接对整个数组进行算术运算的方法。下面我们将前面那个慢速的 Python 示例改写为 UFunc 版本,它就像下面这样:

import numpy as npnp.random.seed(0)values = np.random.randint(1, 100, size=1000000)%timeit result = 1.0/values

改写后的代码不仅提高了速度,而且代码变得更短。猜猜现在这个程序执行要花多少时间?它比我上面提到的最快的语言快了2.7毫秒

每个循环平均耗时2.71毫秒(标准偏差±50.8微秒)(共运行了7次程序,每次循环100个)

返回代码,关键是 1.0/values 这一行。这里的 values 不是一个数字,而是一个 NumPy 数组。和除法运算符一样,Numpy 还有许多其他运算符(如下图示)。

点击这里可以找到所有 Ufunc 运算(操作)符。

总结

对于那些使用 Python 的人来说,使用 Python 处理数据和数字的可能性很大。这些数据可以存储在 NumPy 或 Pandas DataFrame中,因为DataFrame 是基于 NumPy 实现的。所以 Ufunc 也可以使用。

UFunc 使我们能够以超越几个数量级的更快速度在 Python 中执行重复操作。最慢的 Python 甚至可以跑得 C 语言更快。这一点太让人激动了。

附录— C,C#,Java 和 NodeJS 的测试代码

C 语言:

#include <stdio.h>#include <stdlib.h>#include <sys/time.h>
int main(){struct timeval stop, start;int length = 1000000;int rand_array[length];float output_array[length];for(int i = 0; i<length; i++){        rand_array[i] = rand();    }    gettimeofday(&start, NULL);for(int i = 0; i<length; i++){        output_array[i] = 1.0/(rand_array[i]*1.0);    }    gettimeofday(&stop, NULL);printf("took %lu us\n", (stop.tv_sec - start.tv_sec) * 1000000 + stop.tv_usec - start.tv_usec); printf("done\n");return 0;}

C#(.net 5.0):

using System;namespace speed_test{class Program{static void Main(string[] args){int length = 1000000;double[] rand_array =new double[length];double[] output = new double[length];var rand = new Random();for(int i =0; i<length;i++){                rand_array[i] = rand.Next();//Console.WriteLine(rand_array[i]);            }long start = DateTimeOffset.Now.ToUnixTimeMilliseconds();for(int i =0;i<length;i++){                output[i] = 1.0/rand_array[i];            }long end = DateTimeOffset.Now.ToUnixTimeMilliseconds();            Console.WriteLine(end - start);        }    }}

Java:

import java.util.Random;
public class speed_test {public static void main(String[] args){int length = 1000000;long[] rand_array = new long[length];double[] output = new double[length];        Random rand = new Random ();for(int i =0; i<length; i++){            rand_array[i] = rand.nextLong();        }long start = System.currentTimeMillis();for(int i = 0;i<length; i++){            output[i] = 1.0/rand_array[i];        }long end = System.currentTimeMillis();        System.out.println(end - start);    }}

NodeJS:

let length = 1000000;let rand_array = [];let output = [];for(var i=0;i<length;i++){    rand_array[i] = Math.floor(Math.random()*10000000);}let start = (new Date()).getMilliseconds();for(var i=0;i<length;i++){    output[i] = 1.0/rand_array[i];}let end = (new Date()).getMilliseconds();console.log(end - start);

原文链接:https://python.plainenglish.io/a-solution-to-boost-python-speed-1000x-times-c9e7d5be2f40

声明:本文由CSDN翻译,转载请注明来源.

☞为了写论文给 Linux “投毒”,导致整个大学都被 Linux 拉黑!
☞后浪优秀!21 岁小伙兼职程序员养家,大三存款达 6 位数
☞特斯拉成了“特撕拉”,程序员成了背锅侠?你还会买吗?
☞腾讯高级研究员博士论文走红,称“计算机终于成了我一生的事业与希望”
☞19 岁华裔天才辍学创业,5 年市值达 73 亿美元

Python 速度慢,试试这个方法提高 1000 倍相关推荐

  1. 提高计算机访问硬盘的速度慢,如何加快硬盘相应速度?6大方法提高-万兴恢复专家...

    硬盘对于计算机系统的正常工作至关重要.它提供了大量的空间来存储数据.现在每个现代计算机系统都有一个快速和大型的硬盘驱动器,有助于快速检索文件和程序.但是,如果积累太多杂乱,即使最快和最大的硬盘驱动器也 ...

  2. mongodb 搜索速度_MongoDB数据库查询性能提高40倍的经历分享

    前言 数据库性能对软件整体性能有着至关重要的影响,本文给大家分享了一次MongoDB数据库查询性能提高40倍的经历,感兴趣的朋友们可以参考学习. 背景说明 1.数据库:MongoDB 2.数据集: A ...

  3. 新思科技助力IBM将AI计算性能提升1000倍

    与IBM研究院 AI硬件中心合作,解决采用创新设计方法开发全新AI芯片架构方面的挑战 加州山景城2020年12月28日 -- 要点: 新思科技作为IBM AI硬件研究中心的首席EDA和IP合作伙伴,与 ...

  4. 苹果怎么换行打字_2周内将你的打字速度提高3倍的方法

    因为最近打字较多,感觉全拼输入比较慢,就想提高一下打字速度.去学五笔输入,成本实在有点高.有没有尽量不改变拼音输入的习惯,就能大副提升打字速度,而学习成本又不高的方法呢? 百度和知乎搜索了一些零散知识 ...

  5. Python 之父立 Flag:明年要把 Python 速度提高 2 倍!

    整理 | 郑丽媛 出品 | CSDN(ID:CSDNnews) 去年 11 月,退休失败的 Python 之父 Guido van Rossum 在推特上宣布,退休生活太无聊,从而加入了微软开发者部门 ...

  6. 需求调研 现有系统梳理_对速度的需求,访问现有数据的速度提高了1000倍

    需求调研 现有系统梳理 了解如何通过使用标准Java 8流和Speedment的In-JVM-Memory加速器将分析数据库应用程序加速1000倍. Web和移动应用程序有时会很慢,因为后备数据库很慢 ...

  7. 对速度的需求,访问现有数据的速度提高了1000倍

    了解如何通过使用标准Java 8流和Speedment的In-JVM-Memory加速器将分析数据库应用程序加速1000倍. Web和移动应用程序有时会很慢,因为后备数据库很慢和/或与数据库的连接施加 ...

  8. python速度提高了吗_这一行代码,能让你的 Python运行速度提高100倍

    python一直被病垢运行速度太慢,但是实际上python的执行效率并不慢,慢的是python用的解释器Cpython运行效率太差. "一行代码让python的运行速度提高100倍" ...

  9. 电脑速度慢的一些方法

    电脑速度慢的一些方法 电脑速度慢的原因及解决方法 电脑速度慢 对于关机慢的解释:  1.开始 运行msconfig回车,启动,勾选杀毒软件,防火墙,输入法ctfmon三个其他的勾都去掉,确定,关闭,重 ...

最新文章

  1. spring 全局变量_[Spring]-Spring框架-02-IOC容器
  2. Maven官宣:干掉Maven和Gradle!推出更强更快更牛逼的新一代构建工具,炸裂!
  3. RStudio版本号管理 整合Git
  4. 反编译sencha toucha打包的apk文件,修改应用名称支持中文以及去除应用标题栏
  5. 简述大数据的数据管理方式_智能销售服务商荣登TOP100榜,大数据线上获客方式再得认可...
  6. Linux 设备驱动的固件加载
  7. 工作316:uni-修改其他页面的时间逻辑
  8. Safari 是什么
  9. 如何MATLAB中将一个向量或者矩阵强行转换为列向量
  10. ​最高要价 8888元,小米 11 邀请函现身闲鱼;荣耀与微软签署全球 PC 合作协议;Xfce 4.16 发布|极客头条...
  11. 面试官:有没有比读写锁更快的锁?
  12. pic单片机c语言编程优势,PIC单片机与PIC单片机C语言编程简介
  13. 封装程序报错Failed to execute script pyi_rth_multiprocessing解决办法
  14. 数据库基本知识点总结
  15. 骑士人才linux伪静态,骑士CMS人才系统伪静态的设置方法
  16. day55-负载均衡之lvs
  17. 151只宝可梦(神奇宝贝)倒背的我,却连元素周期表都背不过 -- Python 爬虫小课 3-9
  18. oracle 用户权限设置,oracle用户权限管理使用详解
  19. 二进制与十进制转换器
  20. 前端批量生成二维码并打包下载

热门文章

  1. 施一公:世界如此未知,还有什么物事必须难以释怀?
  2. 美国匹兹堡大学高伟教授招收Mobile AI方向全奖博士生
  3. CVPR 9999 Best Paper:一种加辣椒的番茄炒蛋
  4. 医学与人工智能交叉融合,打开眼科理疗新窗
  5. 产权分割商铺,太坑人!
  6. CCAI 2020 | 黄铁军:“仿真主义”下的人工智能发展之路
  7. 少标签数据学习,54页ppt
  8. SAP SD基础知识之现金销售
  9. 如何构建一个成功的AI PoC(概念验证项目)
  10. Nature发文:深度学习系统为什么这么好骗?