百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

Python 速度慢,试试这个方法提高 1000 倍

off999 2024-09-13 13:30 58 浏览 0 评论

作者 | 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, ); for(int i = 0; i<length; i++){ output_array[i] = 1.0/(rand_array[i]*1.0); } gettimeofday(&stop, ); 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翻译,转载请注明来源.

4月20日晚八点,欢迎来到CSDN悦读时间直播间,与四位大咖一起探索UNIX传奇往事的启示,围观《UNIX传奇》新书发布会!


相关推荐

安全教育登录入口平台(安全教育登录入口平台官网)

122交通安全教育怎么登录:122交通网的注册方法是首先登录网址http://www.122.cn/,接着打开网页后,点击右上角的“个人登录”;其次进入邮箱注册,然后进入到注册页面,输入相关信息即可完...

大鱼吃小鱼经典版(大鱼吃小鱼经典版(经典版)官方版)

大鱼吃小鱼小鱼吃虾是于谦跟郭麒麟的《我的棒儿呢?》郭德纲说于思洋郭麒麟作诗的相声,最后郭麒麟做了一首,师傅躺在师母身上大鱼吃小鱼小鱼吃虾虾吃水水落石出师傅压师娘师娘压床床压地地动山摇。...

谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
哪个软件可以免费pdf转ppt(免费的pdf转ppt软件哪个好)
哪个软件可以免费pdf转ppt(免费的pdf转ppt软件哪个好)

要想将ppt免费转换为pdf的话,我们建议大家可以下一个那个wps,如果你是会员的话,可以注册为会员,这样的话,在wps里面的话,就可以免费将ppt呢转换为pdfpdf之后呢,我们就可以直接使用,不需要去直接不需要去另外保存,为什么格式转...

2026-02-04 09:03 off999

电信宽带测速官网入口(电信宽带测速官网入口app)

这个网站看看http://www.swok.cn/pcindex.jsp1.登录中国电信网上营业厅,宽带光纤,贴心服务,宽带测速2.下载第三方软件,如360等。进行在线测速进行宽带测速时,尽...

植物大战僵尸95版手机下载(植物大战僵尸95 版下载)

1可以在应用商店或者游戏平台上下载植物大战僵尸95版手机游戏。2下载教程:打开应用商店或者游戏平台,搜索“植物大战僵尸95版”,找到游戏后点击下载按钮,等待下载完成即可安装并开始游戏。3注意:确...

免费下载ppt成品的网站(ppt成品免费下载的网站有哪些)

1、Chuangkit(chuangkit.com)直达地址:chuangkit.com2、Woodo幻灯片(woodo.cn)直达链接:woodo.cn3、OfficePlus(officeplu...

2025世界杯赛程表(2025世界杯在哪个国家)

2022年卡塔尔世界杯赛程公布,全部比赛在卡塔尔境内8座球场举行,2022年,决赛阶段球队全部确定。揭幕战于当地时间11月20日19时进行,由东道主卡塔尔对阵厄瓜多尔,决赛于当地时间12月18日...

下载搜狐视频电视剧(搜狐电视剧下载安装)

搜狐视频APP下载好的视频想要导出到手机相册里方法如下1、打开手机搜狐视频软件,进入搜狐视频后我们点击右上角的“查找”,找到自已喜欢的视频。2、在“浏览器页面搜索”窗口中,输入要下载的视频的名称,然后...

pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
永久免费听歌网站(丫丫音乐网)

可以到《我爱音乐网》《好听音乐网》《一听音乐网》《YYMP3音乐网》还可以到《九天音乐网》永久免费听歌软件有酷狗音乐和天猫精灵,以前要跳舞经常要下载舞曲,我从QQ上找不到舞曲下载就从酷狗音乐上找,大多...

音乐格式转换mp3软件(音乐格式转换器免费版)

有两种方法:方法一在手机上操作:1、进入手机中的文件管理。2、在其中选择“音乐”,将显示出手机中的全部音乐。3、点击“全选”,选中所有音乐文件。4、点击屏幕右下方的省略号图标,在弹出菜单中选择“...

电子书txt下载(免费的最全的小说阅读器)

1.Z-library里面收录了近千万本电子书籍,需求量大。2.苦瓜书盘没有广告,不需要账号注册,使用起来非常简单,直接搜索预览下载即可。3.鸠摩搜书整体风格简洁清晰,书籍资源丰富。4.亚马逊图书书籍...

最好免费观看高清电影(播放免费的最好看的电影)

在目前的网上选择中,IMDb(互联网电影数据库)被认为是最全的电影网站之一。这个网站提供了各种类型的电影和电视节目的海量信息,包括剧情介绍、演员表、评价、评论等。其还提供了有关电影制作背后的详细信息,...

孤单枪手2简体中文版(孤单枪手2简体中文版官方下载)

要将《孤胆枪手2》游戏的征兵秘籍切换为中文,您可以按照以下步骤进行操作:首先,打开游戏设置选项,通常可以在游戏主菜单或游戏内部找到。然后,寻找语言选项或界面选项,点击进入。在语言选项中,选择中文作为游...

取消回复欢迎 发表评论: