python class namedtuple 效率_python-3.x – 与tuple / dictionary / class相比,namedtuple变慢

我很好奇为什么namedtuple比

python中的常规类慢.考虑以下:

In [1]: from collections import namedtuple

In [2]: Stock = namedtuple('Stock', 'name price shares')

In [3]: s = Stock('AAPL', 750.34, 90)

In [4]: %%timeit

...: value = s.price * s.shares

...:

175 ns ± 1.17 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [5]: class Stock2:

...: __slots__ = ('name', 'price', 'shares')

...: def __init__(self, name, price, shares):

...: self.name = name

...: self.price = price

...: self.shares = shares

In [6]: s2 = Stock2('AAPL', 750.34, 90)

In [8]: %%timeit

...: value = s2.price * s2.shares

...:

106 ns ± 0.832 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [9]: class Stock3:

...: def __init__(self, name, price, shares):

...: self.name = name

...: self.price = price

...: self.shares = shares

In [10]: s3 = Stock3('AAPL', 750.34, 90)

In [11]: %%timeit

...: value = s3.price * s3.shares

...:

118 ns ± 3.54 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [12]: t = ('AAPL', 750.34, 90)

In [13]: %%timeit

...: values = t[1] * t[2]

...:

93.8 ns ± 1.13 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [14]: d = dict(name='AAPL', price=750.34, shares=90)

In [15]: %%timeit

...: value = d['price'] * d['shares']

...:

92.5 ns ± 0.37 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

我期望namedtuple来到没有插槽的课程之前.这是在python3.6上.同样令人惊讶的是,字典的性能可与元组相媲美.

最佳答案 对于python类的一个实例,通过点表示法设置和获取属性主要是通过__dict __ [attribute_name](__ dict__本身是一个属性,它是一个字典)的实例,取决于__dict的值__ [attribute_name]调用它v ,有不同的行为.

情况一:v不是descriptor,所以点符号只返回v.

情况二:v是一个描述符,结果将从描述符的__get__方法中获取.

对于描述中的简单类实例:很容易就是第一种情况

对于namedtuple情况:看看namedtuple source code,函数namedtuple正在使用这个template创建一个类,其中在dict中命名字段存储作为属性.

其中property是描述符,itemgetter实例将在描述符的__get__方法中使用!

这是python代码中的属性类,位于Cpython中c源代码的注释中:

class property(object):

def __init__(self, fget=None, fset=None, fdel=None, doc=None):

if doc is None and fget is not None and hasattr(fget, "__doc__"):

doc = fget.__doc__

self.__get = fget

self.__set = fset

self.__del = fdel

self.__doc__ = doc

def __get__(self, inst, type=None):

if inst is None:

return self

if self.__get is None:

raise AttributeError, "unreadable attribute"

return self.__get(inst)

def __set__(self, inst, value):

if self.__set is None:

raise AttributeError, "can't set attribute"

return self.__set(inst, value)

def __delete__(self, inst):

if self.__del is None:

raise AttributeError, "can't delete attribute"

return self.__del(inst)

总结一下,我们应该理解为什么namedtupple访问速度较慢,有一些额外的步骤可以从nametuple创建的类的实例中获取值而不是简单的类.

如果你想深入挖掘,看看如何存储和获取值,你可以通过上面的链接阅读python3.6的源代码.

提示:

namedtuple创建类是一个子类,将字段值存储为元组,并通过属性存储相关索引及其名称.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值