阅读更多

0顶
0踩

编程语言
大约在一年前,也就是2013年在Waza(地名),Alex Gaynor提到了一个很好的话题:为什么用Python、Ruby和Javascript写的程序总是运行的很慢呢?正如他强调的,关键就是现在出现了这个问题。换一句话说,尽管现在这种语言很慢,但不意味着没有解决办法,不意味着未来会一直这样。

当在网上问为什么Python比C语言更慢,回答最多的就是Python中有动态类型。然而,动态类型确实会在性能方面有影响,但是这并不是主要原因。

动态类型(像Python一样的主要编程语言都一样)使得编译器很难优化性能。动态使得每次执行都可能很不同,编译器难以优化。然而,正如Alex在谈话中提到的,我们花费了数年的时间来研究究竟在运行时进行类型检查的最好的办法是什么。但是没什么进展。

在现实中,在C语言和Python在运行时的巨大的不同是由于数据结构和算法的不同。有时程序员也没有注意到这一点。

用Python写不同的代码

让我们用一个Alex提到的实例来说明问题。一个Python程序员可能很喜欢用下面的例子表示一个平面上的点:

point = {'x': 0, 'y': 0}


这种方法很易读,容易编码,形式很优雅。

另一个方面,一个C语言程序员可能使用结构体来表示平面上的点:

struct Point {
   int x;
   int y;
};


尽管这种方法也和Python能一样的工作并且都是很优雅的,但这是完全不同的数据结构。这里我们告诉了编译器,我们有两个字段x和y。知道了这两个字段的类型,编译器将分配一块连续的内存来储存这两个数据。换一句话说,就像一个数组一样。任何时间,编译器都知道给定的x和y在哪里。我们可以很容易地访问这些数据,就像是访问某些常数据一样。

Python使用哈希散列的方法来解决类似的问题。所以编译器不能简单地分配连续内存存储x和y来处理这些问题。由于我们在其中任意的地方都可能出现这些键。如果我们想的话,我们也可能删除这些键。编译器必须要使用哈希函数来映射到你可能让他指向的任何存储单元。不用说,这些函数增加了处理时间。尽管也许减缓的很小,但是足可以拖慢你的代码,尤其是这种情况如果很多的时候。

如果就是想将Python翻译成C语言的话,可能就像下面这样:

std::hash_set point;
point[“x”] = x
point[“y”] = y


看这个代码片段,好像就是语言的设计者他们自己故意尽力使哈希表复杂,因此尽管是正确的,但没有人使用。由于这个原因,写C语言的人可能认为这是不可思议的,但为什么在Python就是可以接受的呢?

原因就是写Python代码的人的“dictionaries are lightweight objects”这种心态。看下面的代码,这在Python中最接近C语言结构体:

class Point(object):
     x, y = None, None
     def __init__(self, x, y):
          self.x, self.y = x, y


这对编译器是有用的,就像是C语言的结构体。例如第二行,我们明确告诉编译器但我们创造一个对象时我们总是至少需要两个数据段,我们希望编译器处理这个问题。

不幸的是这种标准的Python被叫做CPthon,不能总被使用。在我的机器上,下面的代码要执行186毫秒:

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


在我的机器上,用point.x代替point['x']会花费201毫秒。也就是说,会慢了8%。

在CPthon中,point.x通常就是被处理成dict(point)['x']。这意味着带着点的class仍然像以前一样使用字典(dictionary)的方法查找。这样的话,就很容易看出为什么directionary的方法被看为“轻量级的”。

一些Python写的代码就是为了效率而设计的,例如PyPy,能很快地执行。如果不使用Python而是使用PyPy,同样的代码片段执行时间分别是21.6和3.75毫秒。这种方法相比CPython在JIT-capable编译情况下结果都是令人满意的。换一句话说,PyPy能正确地使用数据结构。

我希望你再一次看这个最短时间3.75毫秒。这个数字表明我们能在一秒进行266000次运算,这些事来自Python的,其中有动态绑定,monkey-patching(在不改变源代码的情况下扩展或修改动态语言运行时代码的方法)等。所有的这些,都是在编码和实现中使用了更好的数据结构。下一次当你在用Python写一行代码时,想一想你在使用什么数据结构,显示的还是隐式的,考虑一下是否有更好的办法。这就是你用C语言写程序时考虑的,不是吗?

最后,我愿意相信这个文章是表明为什么Python是一个有前途的语言的一个清楚的例子(或者是类似的语言)。这表明了标准的Python实现,这里的CPython仅仅是作为一个参考,它从来就不是被设计用来更快地执行的。正如我们今天可以看到的,像PyPy一样的算法实现是可以优化你的代码到一个很好的长度。随着语言的自然发展,这些优化是可能的。我们仅仅用Python编程过23年,那么如果像C语言一样有42年的发展,Python会是什么样子呢?

有人也许会争辩说collections.namedtuple()是更接近于C语言的结构体,这是对的,但我们不要过分将事情复杂化,我们的重点是有效。

为了更清楚python是怎样工作的,请参考python文档。

英文原文:lukauskas.co.uk / 译文:OurJS / 译者:renyuzhuo
来自: OurJS
0
0
评论 共 3 条 请登录后发表评论
3 楼 superleung 2014-03-20 20:46
diggywang 写道
超过Java再说

和JAVA的应用场景不同吧?
2 楼 xsharp 2014-03-18 09:29
diggywang 写道
超过Java再说


如果我回复一下, 会不会显得我很幼稚?
1 楼 diggywang 2014-03-17 22:21
超过Java再说

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • hivemind:Steem区块链上支持社交网络的开发人员友好型微服务

    蜂巢[BETA]支持Steem区块链上社交网络的开发人员友好型微服务。 Hive是Steem区块链的“共识解释”层,保持社交功能的状态,例如发布,订阅和关注以及社区。 它使用Python编写,可将SQL数据库与链状状态同步,从而为...

  • 谈谈Spring IOC是怎么实现解耦的

    最近在看一些东西,突然想到一个面试的问题, SpringIOC是怎么实现解耦的?自己理解的并不好!!那么首先想到的是什么是耦合?怎么做才是解耦?我们都知道在进行软件设计式都遵循一个原则:高内聚,低耦合那么到底...

  • spring-IOC优点和缺点

     Interface Driven Design接口驱动,接口驱动有很多好处,可以提供不同灵活的子类实现,增加代码稳定和健壮性等等,但是接口一定是需要实现的,也就是如下语句迟早要执 行:AInterface a = new AInterface...

  • hivemind-widget:使用Vue JS的Hivemind小部件组件

    Hivemind小工具 使用汇总将一个或多个Vue.js组件捆绑到单个.js文件中的示例,该文件可在任何HTML / JS应用程序中使用。 有关更多信息,请参考上的。 < html > < body > ... <!-- you can add ...

  • Spring VS HiveMind 优点缺点大比拼

    <br /> * HiveMind使用的配置文件格式更清楚简明,特别是将接口和实现统一定义成1个service,而Spring可能要定义好几个bean元素; <br /> * 在增加或移去interceptor时,HiveMind只要修改1行配置

  • Hivemind资料

    hivemind资料 博文链接:https://snail-gtt.iteye.com/blog/113434

  • HiveMind 和 Spring 的比较 (之一)

    HiveMind 和 Spring 从实现的功能上看有很大的部分是重叠的,都是用ICO控制翻转、依赖注射等原理来实现相似的功能,从这一点上讲两者的指导精神是一致的。 存在的就是合理的。HiveMind 和 Spring 实现的方式和关注...

  • hivemind:一种多语法语言

    Hivemind具有由其AST定义的核心语言以及像插件一样可配置的语法。 蜂巢的“语法”概念类似于 文本编辑器的主题 gui应用程序的皮肤 MVC Web应用程序的json / html / xml模板 语法是使用类似代码的示例为核心ast节点...

  • 1-Hivemind和Spring的比较

    在如下方面HiveMind优于Spring: * HiveMind强制... * HiveMind使用的配置文件格式更清楚简明,将接口和实现统一定义成1个service,而Spring可能要定义好几个bean元素; * 在增加或移去interceptor时,HiveMind只要修

  • HiveMind-core:加入Mycroft集体,使用Mycroft-Core Mesh网络的实用程序

    HiveMind的开发人员已通过PinePhone,2009 MacBook和Raspberry Pi 0等设备成功连接到Mycroft。 Mycroft本身通常可以在我们的台式计算机或家庭服务器上运行,但是您可以将任何Mycroft品牌的设备或用作中央单元。统计...

  • hivemind_Linux对游戏的支持,Alienware Alpha引入了HiveMind等

    在本周的版本中,我们将了解Linux对CRYENGINE的支持,Alienware Alpha引入了HiveMind等。 2015年6月21日至27日开放游戏摘要 色氨酸3.8.1。 添加了OpenGL和Linux支持 Crytek已发布CRYENGINE版本3.8.1。 ,它...

  • HiveMind 和 Spring 的比较(之二)

     从上文的 HiveMind 和 Spring 总体架构图片你可以看出 两者的结构差异很大。首先,Spring提供了一套完整的组件,从页面展示的MVC框架到后台的数据库ORMapping等统统都有,其中有些是Spring自有的,有些则提供了...

  • hivemind:PyTorch中的分散式深度学习。 旨在为全球数千名志愿者训练模型

    Hivemind是一个PyTorch库,用于在Internet上训练大型神经网络。 想象一下,在来自不同大学,公司和志愿者的数千台计算机上训练一个巨大的Transformer模型。 主要特点 训练任意大小的神经网络:其各层的一部分分布在...

  • HiveMind-js:HiveMind JavaScript客户端

    HiveMind JS HiveMind的javascript客户端 用法 <!DOCTYPE html > < html > < head > < meta charset =" UTF-8 " > < title > HiveMindJs Demo </ title > < script src =...

  • HiveMind Java Web Application Cloud IDE:浏览器中的Web开发IDE,支持Java,ruby,javascript ... etc-开源

    HiveMind是基于浏览器的Web开发,结合​​了在浏览器中运行的应用程序容器(码头),中间件和开发人员环境。 它在jvm上运行,因此您不受环境的限制。 您可以在笔记本电脑,公司服务器甚至AWS等云服务上运行它。 它...

  • 从IOC方面谈谈我个人对Spring方便解耦这点的理解

    本篇文章记录了我个人对Spring框架能够解耦这一优点的理解,将它分享出来和大家一起学习交流,同时也欢迎大家纠错改正 相信大家对 Spring 的 IOC 和 DI 并不陌生了,它们为 Spring 框架带来了方便解耦这一优点...

  • Spring的IOC原理

    发现一篇不错的文章,目测是网上解释这个概念最清楚的文章了,转来学习一下,原文是Spring的IOC原理 [通俗解释一下]略做了一下排版,方便阅读。以下是正文:1. IoC理论的背景我们都知道,在采用面向对象方法设计的...

  • hivemind-1.1.1.jar

    hivemind-1.1.1.jar

  • 天然气汽车供气系统减压装置毕业设计(cad+设计方案).zip

    天然气汽车供气系统减压装置毕业设计(cad+设计方案)

  • PHP+SQL考勤系统安全性实现(源代码+论文+答辩PPT+指导书)

    PHP+SQL考勤系统安全性实现(源代码+论文+答辩PPT+指导书)

Global site tag (gtag.js) - Google Analytics