范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

python的numpy向量化语句为什么会比for快?

  我们先来看看,python之类语言的for循环,和其它语言相比,额外付出了什么。
  我们知道,python是解释执行的。
  举例来说,执行 x = 1234+5678 ,对编译型语言,是从内存读入两个short int到寄存器,然后读入加法指令,通知CPU内部的加法器动作,最后把加法器输出存储到x对应的内存单元(实质上,最后这个动作几乎总会被自动优化为"把加法器输出暂存到寄存器而不是内存单元,因为访问内存的时间消耗常常是访问寄存器的几十倍")。一共2~4条指令(视不同CPU指令集而定)。
  换了解释性语言,情况就大大不同了。
  它得先把"x = 1234+5678"当成字符串,逐个字符比对以分析语法结构——不计空格这也是11个字符,至少要做11个循环;每个循环至少需要执行的指令有:取数据(如读"x"这个字符)、比较数据、根据比较结果跳转(可能还得跳转回来)、累加循环计数器、检查循环计数器是否到达终值、根据比较结果跳转。这就是至少6条指令,其中包含一次内存读取、至少两次分支指令(现代CPU有分支预测,若命中无额外消耗,否则……)。总计66条指令,比编译型语言慢至少17倍(假设每条指令执行时间相同。但事实上,访存/跳转类指令消耗的时间常常是加法指令的十倍甚至百倍)。
  这还只是读入源码的消耗,尚未计入"语法分析"这个大头;加上后,起码指令数多数百倍(消耗时间嘛……我猜起码得多数千倍吧)。
  不过,python比起其它解释性语言还是强很多的。因为它可以事先把文本代码编译成"字节码"(存储于扩展名为pyc的文件里),从而直接处理整型的"指令代码",不再需要从头开始分析文本。
  但是,从"字节码"翻译到实际CPU代码这步,仍然是省不下的。
  这个消耗,可看作"利用虚拟机"执行异构CPU上的程序。有人证明过,哪怕优化到极致,这也需要10倍的性能消耗。
  这个消耗也有办法缩减。这就是JIT技术。
  JIT说白了,就是在第一遍执行一段代码前,先执行编译动作,然后执行编译后的代码。
  如果代码中没有循环,那么这将白白付出很多额外的时间代价;但若有一定规模以上的循环,就可能节省一点时间。
  这里面的佼佼者是Java。它甚至能根据上次运行结果实时profile,然后花大力气优化关键代码,从而得到比C更快的执行速度。
  不过,理想很丰满,现实很骨感。虽然局部热点的确可能更快,但Java的整体效率仍然比C/C++差上很多——这个原因就比较复杂了。
  和C/C++/Java那种投入海量资源经过千锤百炼的编译器不同,python的JIT甚至可称得上"蹩脚"。
  加加减减,仅一个循环,慢上十几甚至几十倍还是很正常的。
  以上讨论,仅仅考虑了for循环这个控制结构本身。事实上,"慢"往往是全方位的。
  举例来说,要计算一组向量,首先就要存储它。
  怎么存储呢?
  对C/C++来说,就存在"数组"里;而它的数组,就是赤裸裸的一片连续内存区域;区域中每若干个字节就存储了一个数值数据。
  这种结构CPU处理起来最为方便快捷,且cache友好(若cache不友好就可能慢数倍甚至数十倍)。
  Java等其它语言就要稍逊一筹。因为它的"数组"是"真正的数组";相对于"连续内存区域","真正的数组"就不得不在每次访问时检查数组下标有无越界。这个检查开销不大,但也不小……
  当然,这也是有好处的。至少不用像C/C++那样,整天担心缓冲区溢出了。
  而python之类……
  为了迁就初学者,它去掉了"变量声明"以及"数据类型"——于是它的用户再也用不着、也没法写 int xxx了。随便什么数据,咱想存就存,乌拉!
  但是,如果我告诉你,可变数据类型其实在C/C++里面是这样声明的呢: typedef struct tagVARIANT {   union {     struct __tagVARIANT {       VARTYPE vt;       WORD    wReserved1;       WORD    wReserved2;       WORD    wReserved3;       union {         LONGLONG            llVal;         LONG                lVal;         BYTE                bVal;         SHORT               iVal;         FLOAT               fltVal;         DOUBLE              dblVal;         VARIANT_BOOL        boolVal;         _VARIANT_BOOL       bool;         SCODE               scode;         CY                  cyVal;         DATE                date;         BSTR                bstrVal;         IUnknown            *punkVal;         IDispatch           *pdispVal;         SAFEARRAY           *parray;         BYTE                *pbVal;         SHORT               *piVal;         LONG                *plVal;         LONGLONG            *pllVal;         FLOAT               *pfltVal;         DOUBLE              *pdblVal;         VARIANT_BOOL        *pboolVal;         _VARIANT_BOOL       *pbool;         SCODE               *pscode;         CY                  *pcyVal;         DATE                *pdate;         BSTR                *pbstrVal;         IUnknown            **ppunkVal;         IDispatch           **ppdispVal;         SAFEARRAY           **pparray;         VARIANT             *pvarVal;         PVOID               byref;         CHAR                cVal;         USHORT              uiVal;         ULONG               ulVal;         ULONGLONG           ullVal;         INT                 intVal;         UINT                uintVal;         DECIMAL             *pdecVal;         CHAR                *pcVal;         USHORT              *puiVal;         ULONG               *pulVal;         ULONGLONG           *pullVal;         INT                 *pintVal;         UINT                *puintVal;         struct __tagBRECORD {           PVOID       pvRecord;           IRecordInfo *pRecInfo;         } __VARIANT_NAME_4;       } __VARIANT_NAME_3;     } __VARIANT_NAME_2;     DECIMAL             decVal;   } __VARIANT_NAME_1; } VARIANT, *LPVARIANT, VARIANTARG, *LPVARIANTARG;
  简单说,这玩意儿的思路就是"利用一个tag指示数据类型,真正的数据存储在下面的union里;访问时,依据tag指示转换/返回合适类型"。
  很显然,对C/C++/Java程序员来说,这玩意儿无论时间还是空间上,都是个灾难。
  并且,它也极度的cache不友好——本来可以连续存储的,现在……变成了个结构体;而且一旦存了某些类型的数据,就不得不通过指针跳转到另一块区域才能访问(如果原地存储,浪费的空间就太恐怖了)。
  所以你看,咱要基于这种结构谈效率,是不是有点……
  哪怕仅仅了解到这个程度也已经很是触目惊心了:解释执行+字节码优化慢上至少10倍到几十上百倍,"初学者友好"的基础数据又慢上几倍到几十倍,透过容器访问(而非性能更好的、固定大小数组乃至不检查下标假装自己是数组的"内存区域")再慢上几倍到几十倍……哪怕咱暂时不考虑其它机制带来的开销,仅把这几样往一块一凑(在某些特定的情况下,这些不同的"慢"点还可能相互影响、起到"迟缓度倍增放大"的效果)……
  除此之外,还有python内部如何管理/索引/访问脚本中的全局/局部变量的问题(一般会用dict)、用户数据和物理机存储器严重不匹配引起的缓存未命中问题、python内部状态机/执行现场管理等等方面管理的问题——对编译型语言,这些统统不存在,CPU/内存自己就把自己照顾的很好了;但对解释性语言,这些都会成为"迟缓度倍增"的元凶。
  这些东西的相互影响极为复杂微妙,几乎没人能彻底搞明白它。
  你看,明白了前因后果,咱是不是只能说"python的优化实在不错,才仅仅慢了20万倍而已"呢?(笑~
  当然,如果不做这类较为复杂的处理,仅仅是一些流程性的东西的话,这类语言的处理速度还是够用的——至少与之交互的人感受不到丝毫延迟。
  甚至,哪怕需要复杂的处理,这类语言也可以向其它语言求救啊。就好像有个numpy,谁敢说python做不了向量运算呢?
  ——当然,和行家说话时,你得明白,这是找C之类语言搬救兵了。睁眼说瞎话把它当成python语言自己的能力是有点丢人的。不过如果只混python的圈子的话,这倒也不耽误什么。
  ————————————————————————————
  如果要揭短,专业程序员还会把无数据类型导致接口模糊所以无法写较为复杂的程序之类弊端给你列出一火车的。但这些就是没必要的题外话了。
  毕竟,python只是个胶水语言,初学者友好并且应付常见的简单应用场景绰绰有余,这已经足够了。
  就好像把office做的傻瓜化,本就是专业程序员的工作一样——用户觉得好用、乐意掏钱就行了,何必关心"做出一套office需要砸进去的钱足够盖N座迪拜塔"呢。
  当然,如果想进一步发展的话,请记住"在合适的地方用合适的工具"这句话——然后想办法搞明白每种工具的局限性吧。
  毕竟,哪怕是C/C++,在做矩阵之类运算时,也还会求助于SIMD的MMX指令、超线程/多核心CPU乃至GPU,以便为自己"增补"上并行处理能力呢。

国美真快乐APP拉新,价格置顶国美真快乐APP拉新,价格置顶客户端展业流程第一步应用商店下载真快乐APP,手机号登录后扫推广码第二步扫码后进入新人一元购页面,领取优惠券后在1元必买区选择抢购煌上煌鸭脖休闲零食(为防山寨和被蹭热度,VIVO申请了VIVQIOOQ等多个防御性商标为防山寨和被蹭热度,VIVO申请了VVOIOOQVIVQ多个商标VIVO作为国产手机四大厂商之一,除了在专利申请方面非常积极之外,对于自己的商标保护同样相当舍得投入。日前为了防止自行业大事记广汽埃安超倍速电池技术极氪子品牌极氪能源蜂巢能源无钴电池包量产装车比亚迪首搭5G版智能网联系统能源人都在看,点击右上角加关注整车1理想汽车公布Q2财报8月30日,理想汽车公布Q2财报。Q2收入总额为50。4亿元,较去年同期增长158。8,较2021年第一季度的35。8亿元增解锁企业福利采购新路径,京东推出商品服务一站式采购解决方案中秋临近,员工福利的采买和发放已经在企业采购人的日程上标红加粗。中秋福利是员工最关注的节日福利之一,也是企业文化的传达。虽然中秋发福利已经是很多企业的传统,但如何在更及时的时间内高阿里巴巴联合金龙鱼,共同打造餐饮平台消费升级看似平静的本地生活服务赛道已经暗潮汹涌,据悉,阿里巴巴目前正与国内一线品牌油商金龙鱼接洽本地生活餐饮平台的相关事宜,以餐厅食用油信息显示系统,来为外卖堂食等网络餐饮交易平台开启餐饮库克之道,5年后的接任者会更像乔布斯?最佳继任CEO,可能也是最佳CEO。库克会如何选自己的接任者文常青库克任职苹果公司CEO10周年的纪念,变成了对库克的一片肉麻歌颂终于到了一个相当肉麻的程度。几个月前,彭博商业周刊这三款高端旗舰面世快一个月了,都怎么样?八月份本来在数码圈里就不是太过热闹的时间,但是今年的8月份却是非比寻常,一款接一款的创新型旗舰机接连面世,俘获了一大批数码爱好者的欢心。但是,千万要冷静,因为最初的一批使用者都或多万万没想到!OPPOA53竟成Q2最畅销安卓机,三大亮点加持随着5G时代的到来,手机厂商间的竞争也是越来越激烈,各大手机厂商不断推陈出新,发布了多款不同价位各具特色的5G手机,OPPO也不例外。近日绿哥发现OPPO去年发布的OPPOA53,韩国将成为世界上首个打破App商店支付垄断的国家北京时间8月31日,据韩联社报道,韩国国会31日表决通过电子通信事业法修正案,禁止应用平台运营商利用自身地位强迫开发者使用特定支付方式的行为。上述法案将在韩国总统签字后正式生效。若资讯新能源车产业渗透率持续提升中国忠旺铝推轻量化进程中国汽车工业协会数据显示,7月份中国新能源汽车销量27。1万辆,再创单月销量历史新高,同比增长164。4,环比增长5。8。17月新能源汽车累计销量147。8万辆,同比增长197。1宏光MINIEV质量靠谱吗?保值率这块,已居于新能源车榜首在新能源车市场不少车企都不遗余力在提升自身实力努力打造更保值市场更喜爱的车型。不过和燃油车市场有区分的是,最受欢迎保值率最高的往往并不是那些大块头的高端车,而是一个十足亲民实用的代
安卓手机厂商尴尬了?不待见华为的鸿蒙OS,却遭到美国谷歌调查相关科技资讯援引SamMobile消息称收购并主导Android迭代的美国谷歌,正在寻求第三方App开发者提供反馈收集安卓机型杀App后台数据,从而进行深入调查也就是说,不待见鸿蒙性能赶上A14!骁龙895跑分曝光,首批搭载的厂商包括这几家?按照惯例,高通将在年底发布新一代旗舰处理器。据外媒最新爆料的信息显示,高通新一代旗舰处理器的命名将延续此前的规律,或将命名为骁龙895,并且曝光了其性能表现,相对于目前的骁龙8885亿美元已到账?拒绝华为终于尝到甜头,欧盟分歧却越来越大随着科学技术的快速发展,中国在许多方面已经取得了巨大的成就,其中最成功的自然是华为的5G技术了。在这项科研成果还没有展现时,被多个国家不看好,也有许多的质疑和猜测,中国面对这些言论国产手机厂商集体进军平板电脑市场,这一次他们能斗得过iPad的吗近期,多家国产手机厂商要进军平板电脑市场的消息越来越多,之前已经停更许久的小米平板被曝即将推出新一代的小米平板电脑,传统国产手机厂商vivo已经注册了vivoPad商标OPPO旗下面板价格涨不停,电视厂商终于撑不住了由于疫情导致的产能下降,如今面板价格已经连续涨价超过一年,这在历史上实属首次,不过这种情况一直让电视厂商苦不堪言。因为面板作为电视最重要的组成部分,也是成本最高的零件,所以面板长期手机NFC可以复制小区用的门禁卡吗?你好,很高兴能够回答这个问题。我是一位科技领域创作者,也对NFC有过一定的了解。下面是我的回答想要知道手机NFC是否可以复制小区的门禁卡,首先大家需要搞清楚小区的门禁卡是哪种类型的鸿蒙2。0公测升级,这3款手机可以升级了华为在6月举行的发布会上正式推出了鸿蒙系统,这也表示华为鸿蒙系统正式成为面向市场推出的产品,华为鸿蒙2。0系统升级更新支持近百款机型升级,到现在已经有60多款华为智能手机支持鸿蒙2华为还是输了!麒麟9000对比晓龙888,差距不是一星半点(首发)12月1日,高通最新旗舰芯片骁龙888揭开神秘面纱。高通将骁龙888称之为高通技术的集大成。从各方面来看,这一次高通不再挤牙膏,给人不小的惊喜。据悉,骁龙888测试样机在安兔兔上获iphone手机非常严重的Bug来了,用苹果的你有遇到过吗?Hello,小伙伴们,爱爆料最新消息的清清,又上线了啦,猜猜清清今天将给大家带来啥好消息呢,我们一起来往下看看吧!爱用iPhone手机的用户们,在使用iPhone的时候有没有遇到不用红米手机很丢人吗?不丢人,没实力用苹果手机的才丢人,手机就是工具而已,苹果我买的起,但我认为不值。谁说用红米手机丢人了?一个手机能代表你的身份吗?你还以为是那个用大哥大的年代,拥有一个大哥大就是大款鸿蒙OS耗电太快,怎么办?要么买个发电机,如果钱实在太多,自备核电站把手机砸了!目前还没有发现鸿蒙耗电比较快,建议卸载一些不常用的软件。我的鸿蒙怎么耗电反而慢了?刚升级完鸿蒙系统需要优化过程,一两天后鸿蒙系